简介:金融行业核心系统上云是近年来的热门议题,这份PPT从一家传统寿险公司的IT困境切入,系统梳理了新一代金融核心业务系统云架构的建设路径与关键抉择,适合金融企业技术管理者、架构师以及云平台规划人员参考。资源包内为单个PPT演示文稿,压缩包大小2.58MB,以图文形式覆盖项目现状、建设目标、云部署模式与服务模式选择,并重点说明PaaS层10个组件的来源、分工及自建/购买情况,帮助读者较快建立整体认知。内容还以批处理平台为例,完整呈现从原有Batch平台向Batch PaaS改造的过程,包括引入ZooKeeper实现分布式并行计算、动态节点管理和故障自动转移,以及多租户数据、性能、安全隔离的落地做法,能直接用于类似系统的方案设计或汇报演示。目前已有91人学习浏览,对想了解保险核心系统云化路径、批处理平台PaaS化细节的读者,是一份难得的实践复盘与架构参考。
1. 金融核心系统上云:先别谈 IaaS,把批处理做成 PaaS 再说
这份 PPT 讲的是一个典型矛盾:一边是云技术发展如火如荼,一边是传统金融公司 IT 还陷在 JDK 1.4.2 和 JSP+Servlet 的老坑里。作者给了个非常务实的答案——不是推倒重来上 IaaS,而是把现有系统里最痛、最独立的批处理能力先抽出来,改造成 PaaS。这个思路对中小型金融机构尤其有参考价值:资源有限、业务年增长 50%+、核心系统跑不稳,却还要支撑未来十年的业务量。如果你是传统行业里做架构转型、平台建设的从业者,这份材料能帮你少走不少弯路,关键是怎么拆、怎么选型、改造到什么粒度。
2. 云平台选型:十个 PaaS 组件,哪些该买、哪些必须自建
2.1 部署模式与服务模式:混合云是远期,当下先落在私有云
PPT 对部署模式的规划分了三层:公有云、私有云、混合云(远期)。这里头有个关键判断:对于持牌金融机构,核心业务系统短期内不可能放在公有云上跑,安全和合规是硬约束。所以公有云只是远期选项,当下实际落地的重心在私有云——用 VMware 管虚拟机,Oracle 12C 做数据库,Weblogic 12C 做中间件,这些都是已购资产。
服务模式上,IaaS 三个、PaaS 十个、SaaS 待规划,这个结构很说明问题。SaaS 对这家公司来说太激进,PaaS 才是真正发力的地方。我在做类似项目的时候,会先画一张分层图:底层 IaaS 只解决资源供给问题,PaaS 层才是开发效率的杠杆,SaaS 层则要往后放。选型原则通常是:越靠近基础设施层,越优先复用已购商业产品;越靠近业务能力层,越倾向自建或二次开发。
提示:私有云不是必须从零搭一套 OpenStack,用 VMware 加自动化脚本也能形成私有云的资源池,关键是形成「申请—审批—自动交付」的闭环。
2.2 PaaS 十个组件的选型决策:商业产品 7 个、自主设计 6 个
这是整个 PPT 信息密度最高的一页,直接看组件清单和状态:
| 组件 | 能力说明 | 建设方式 |
|---|---|---|
| IBM BPM | 流程管理 | 购买 |
| IBM ODM | 规则管理(保险产品规则、基本法) | 购买 |
| ECM | 内容管理 | 自建,实施中 |
| Monita | 监控平台 | 自建,实施中 |
| DTX | 分布式事务管理 | 购买 |
| UM | 用户管理 | 自建 |
| Batch | 批处理平台 | 二次开发 |
| Report | 报表平台 | 自建 |
| CIPS | 渠道接入平台 | 购买 |
| PF | 产品工厂 | 自建 |
商业产品 7 个、自主设计 6 个,数字有重叠,说明有的组件是商业产品加自建改造混合的。选型逻辑值得拆一下:流程管理和规则管理直接用 IBM 的成熟产品,因为保险行业的产品规则、销管基本法极其复杂,自建成本极高;而批处理、用户管理这类与具体业务紧耦合、又需要深度定制的能力,选择自建更可控。
我做选型时有一条经验:先看这个组件是不是行业标准化的。BPM、规则引擎、分布式事务国际上都有成熟标准,买比造划算;而批处理平台涉及大量内部系统的任务编排和资源管理逻辑,外部产品套不上,必须自己拆。另一个判断维度是差异化程度——凡是能成为公司效率壁垒的,自建;凡是买了就能用的通用能力,别碰。
2.3 与常见云架构演进路径的差异:利用遗留系统而非推倒重来
这里值得多说一句。PPT 花了一整页强调「跟别人有点不一样」,三个不一样分别是:充分利用遗留应用系统、充分利用已购买软硬件资产、充分利用现有人员的知识技能。
这条原则非常关键,尤其在 IOE 架构向云原生架构演进的过程中,很多团队容易走极端——要么一切重来,要么死守旧系统。作者给的折中路径是:在遗留系统旁边建一层 PaaS,把共性能力抽出来,老系统逐步接入。这样做的好处是风险可控,每一期都有可交付的成果;代价是架构上会有过渡期的割裂感,需要靠接口层去弥合。
注意:这里是私有云加已购资产复用,不是从零买新硬件。预算有限的团队,第一件事永远是盘资产,而不是列采购清单。
3. 批处理平台改造实录:Job/Task/Executor 三级模型与多租户隔离的实现
3.1 核心抽象:一个并行计算任务拆成 Job、Task、Executor 三层
PPT 对批处理平台的定义很清晰:提供批处理开发、批处理运行管理两部分功能,主要用于大批量数据的统一处理,比如分红批处理、满期批处理。这批作业的共同特点是数据量大、计算密集、对完成时间有硬性要求。
平台的核心抽象是三级模型:
- Job:一个完整的并行计算任务,对应一次业务批处理;
- Task:Job 被拆分成多份并行执行,每一份叫一个 Task;
- Executor:真正执行 Task 逻辑的执行者,需要开发人员实现。
这里有个极易被忽视的设计点:开发人员需要学习五个基本概念,但真正要实现的只有三个子类——Executor、SharedResourceHolder、任务拆分逻辑。这个设计把使用门槛压到了最低。
以 Java 为例,Executor 的典型实现骨架是这样的:
public class DividendExecutor extends AbstractTaskExecutor { @Override public void execute(TaskContext context) { // 从共享资源中获取数据源和连接池 DataSource ds = SharedResourceHolder.getInstance().getDataSource(context.getTenantId()); // 按任务分片参数处理数据 String batchId = context.getTaskParam("batchId"); String policyRange = context.getTaskParam("policyRange"); processDividend(batchId, policyRange, ds); } private void processDividend(String batchId, String policyRange, DataSource ds) { // 实际的批量分红计算逻辑 } }这段代码的逻辑说明:Executor 不关心 Job 是怎么拆分的,它只收到一个 TaskContext,从里面取任务参数和租户标识,再从 SharedResourceHolder 获取对应的数据源,然后执行自己负责的那份数据。任务拆分逻辑由框架层负责,通过 ZooKeeper 协调各节点把 Task 分发到不同的 Executor 上。
SharedResourceHolder 的设计意图是封装公共操作,比如初始化数据库连接池、缓存连接池、Spring 上下文。它的典型实现是注册表模式。开发人员通常不需要动它,框架初始化时一次性加载全部共享资源。
3.2 三级模型的关键参数与实现
TaskContext 中几个关键参数决定了任务的边界:
taskId:任务分片唯一标识,用于故障恢复时定位断点;tenantId:租户标识,多租户隔离的数据路由依据(下一节详述);taskCount/taskIndex:总任务份数、当前份索引,用于分片计算;jobId:所属 Job,用于关联日志和监控。
动态增加或删除节点的能力是这套模型的价值所在。加入一个节点后,ZooKeeper 自动感知,后续的任务拆分会按新的节点集合重新分配;节点故障时,已分配的 Task 会被重新调度到存活节点。我通常会建议运维团队把节点注册做成自动化脚本,避免手动在管理页面上加减。
3.3 原部署结构改造与多租户设计
PPT 里专门对比了改造前后的结构差异。原批处理平台最大的问题有三个:用户能查看和管理所有批处理(安全风险);批处理自动分配到所有服务器执行(资源争用);数据库访问由批处理程序自行设定(安全风险)。
改造后的多租户设计有几个具体变化:用户只能查看和管理自己的批处理;用户的批处理自动分配到自己的服务器执行(性能隔离);用户仅能访问自己的数据库(数据隔离)。这个隔离不是简单地在数据库表上加一个 tenant_id 字段,而是从资源调度到数据访问全链路隔离。
租户路由的核心实现,我会在数据源工厂里做一层按租户的映射:
public class TenantAwareDataSourceFactory { private Map<String, DataSource> tenantDataSources = new ConcurrentHashMap<>(); public DataSource getDataSource(String tenantId) { return tenantDataSources.computeIfAbsent(tenantId, id -> { // 每个租户独立数据库连接配置,由批处理管理平台授权后自动创建 HikariConfig config = new HikariConfig(); config.setJdbcUrl(buildJdbcUrl(id)); config.setUsername(getTenantDbUser(id)); config.setPassword(getTenantDbPassword(id)); config.setMaximumPoolSize(20); return new HikariDataSource(config); }); } private String buildJdbcUrl(String tenantId) { // 实际场景中租户 DB 地址从元数据表读取 return "jdbc:oracle:thin:@//dbserver-" + tenantId + ":1521/ORCL"; } }逻辑说明:这里用 TenantId 做数据源缓存和路由的 key,每个租户拿到的是完全独立的数据库连接配置。即使其中某个租户的批处理把连接池打满,也不会影响其他租户的任务执行,这就是 PPT 里说的数据隔离和性能隔离落地方式。
安全隔离则通过授权机制实现:租户的批处理 Job 只能在其被授权的服务器节点上运行,节点和数据库的授权、回收都由专门的服务器管理功能负责,走申请、审批、授权使用、授权回收的闭环流程。
提示:多租户隔离如果要做彻底,虚机层面的隔离也要做。PPT 里的做法是按租户将计算节点分组,租户的 Job 由调度器强制绑定到租户所属节点池,这套逻辑要在任务分发层实现,而不是依赖运维手工操作。
3.4 动态分配:VMware 接口自动创建虚机,批处理马上提速
动态分配是批处理平台 PaaS 化的核心亮点。原系统的资源分配方式是:所有用户能使用的服务器预先安装配置好,需要增加资源时走审批流程甚至采购流程,整个周期按周计算。
改造后的流程变成了:计算资源不足时,用户申请计算节点;虚机管理员审批;系统自动调用 VMware 接口,按需创建虚机;批处理管理员授权给用户;用户的 Job 马上就能用上新节点。我整理了一份资源申请接口的伪代码,可以直观看到这部分的自动化程度:
def provision_compute_node(tenant_id, node_type="batch-worker", cpu=8, memory=16): # 1. 校验租户配额,防止无限申请 current_usage = get_tenant_usage(tenant_id) quota = get_tenant_quota(tenant_id) if current_usage + 1 > quota.max_nodes: reject_request(tenant_id, reason="配额不足") return # 2. 调用 VMware API 创建虚拟机 vm_info = vmware.create_vm(template="batch-worker-template", cpu=cpu, memory=memory, datastore=select_datastore(tenant_id)) # 3. 等待虚机启动并自动完成中间件安装和节点注册 wait_for_ready(vm_info.ip, timeout=300) register_worker_to_zookeeper(tenant_id, vm_info.ip, "batch-group-" + tenant_id) # 4. 通知批处理管理员授权 send_approval_request(tenant_id=tenant_id, node_ip=vm_info.ip)逻辑说明:register_worker_to_zookeeper这一步是动态扩容的关键,虚机创建完成后自动加入 ZooKeeper 的节点分组,调度器立即感知该节点可用,新提交的任务会被分配到新节点。授权环节仍然保留人工审批,这是金融机构的安全底线。
PPT 明确说了管理节点一般不是性能瓶颈,动态分配 Oracle DB、Weblogic 尚未实现。也就是当前版本的动态分配只针对运算单元的服务器,数据库和中间件的动态化还在路上,这一条在项目验收时要想清楚范围。
4. 常见问题排查:批处理 PaaS 化改造中容易翻车的五个坑
4.1 租户隔离只做了字段没做连接路由,数据库全串了
现象:多租户改造上线后,A 租户的批处理任务偶发读到 B 租户的数据。
原因:开发团队在任务和对象层面加了 tenant_id 字段,但数据源是共用的,Executor 没有从 TaskContext 获取租户标识去切换数据库连接。
解决:把数据源路由放到框架层统一处理,Executor 的代码里永不允许自行创建数据库连接,只能通过 SharedResourceHolder 按租户取。凡是绕过框架直连数据库的代码,在代码评审阶段一票否决。从那以后我每次都强制检查一句话:新增代码里有没有裸的 DriverManager.getConnection。
4.2 动态申请虚机没设配额,资源被单一租户占满
现象:无限额放开动态申请后,某个租户提交了海量批处理,把整个资源池占满,其他租户任务全部排队等待。
原因:动态分配实现了自动化,但缺少配额控制。PPT 里的审批流程只校验了「审批动作本身」,没有做总量控制。
解决:给每个租户设置最大节点数和总计算资源配额,在自动申请脚本里先做配额检查,超限直接拒绝并告警。同时为不同租户的节点创建独立的资源池分组,保证单个租户即使打满自己配额,也不能影响其他租户。
4.3 ZooKeeper 会话超时配置不当,批量高峰时节点大面积抖动
现象:批处理高峰时段,大量 Task 被重复调度,任务执行时间不降反升。
原因:ZooKeeper 会话超时时间设置太短(比如默认的 10 秒),虚拟机的 GC 停顿或网络抖动就导致节点会话过期,框架误判节点故障,把正在执行的 Task 重新调度到其他节点,引起重复计算。
解决:把会话超时时间调到 30 到 60 秒,同时加上『会话即将过期』的监听器,在真正过期前尝试续约。另外给 Executor 的任务处理加上幂等控制,用 taskId 做去重,这样即使发生极端的重复调度,也不会产生重复的分红数据。这类问题在测试环境很难复现,都是上了生产赶上高峰才暴露。
4.4 遗留 JDK 1.4.2 程序迁到并行框架,线程安全集体翻车
现象:老批处理程序迁到新平台后,偶尔出现计算结果错乱,没有异常日志,极难定位。
原因:老程序是单线程模型,用了大量 SimpleDateFormat、静态 Map 这类非线程安全对象,拆成多 Task 并行执行后,共享状态被并发写坏。
解决:迁移前先做一轮静态代码扫描,重点排查静态可变对象、SimpleDateFormat、单例里的成员变量。处理方式是把这些对象改成局部变量或用 ThreadLocal 包装。这个坑在 PPT 里没有展开,但任何一个做批处理并行的团队都会遇到,迁移工作量往往比想象中大一倍。
4.5 ZooKeeper 管理的协调节点变成隐晦的单点
现象:管理节点(Distributor)所在服务器宕机,批处理平台整体不可用,即使 ZooKeeper 集群完全正常。
原因:ZooKeeper 做了集群部署,但任务分发逻辑只部署了一个实例,没人想到分发模块本身也需要双活。
解决:把分发模块也做成多实例,通过 ZooKeeper 选主,主节点分发任务,备节点实时同步状态,主节点故障时秒级切换。这类问题表面上是架构问题,实际上是团队对 PaaS 的「无单点故障」要求理解不透彻,PPT 原文写的是无单点故障,每一层都要过一遍这个检查。
5. 方法论复制:从 Batch PaaS 到 UM PaaS,六个基础模块的落地路径
5.1 UM PaaS 拆解:用户管理不只是登录认证
PPT 的第四部分实例是用户管理平台(UM PaaS),在保险 IT 场景里,用户管理的复杂性被严重低估。这个系统不只是登录和会话管理,它要支撑的是 2 万名总用户、10 万名销售人员、以及内外勤多套体系的账号、角色、权限、组织关系管理。
UM PaaS 的隔离设计也复用了批处理平台的多租户模式:每个租户有自己的一套用户体系,租户管理员可以管理本租户内的用户、角色、权限分配,框架层提供统一的认证入口和权限判定服务。对于保险公司来说,渠道差异导致权限模型差异极大——个险渠道、银保渠道、经代渠道的销售基本法完全不同,组织架构和权限模型必须可配置化。
我理解的 UM PaaS 分层结构是:底层是统一用户存储和认证引擎,中间层是权限模型(RBAC 加扩展的属性权限),上层是按渠道配置的租户隔离策略。
5.2 从 Batch 到 UM 的路径复现:四步走也能用在其他模块
Batch PaaS 的落地路径是四步:识别能力边界、定义隔离模型、确定动态扩展机制、建设管理审批流程。这个方法论可以原样搬到 UM PaaS 上:
第一步,识别能力边界。批处理的边界是「大批量数据计算」,UM 的边界是「统一的用户、认证、权限」。边界以内的功能收归平台,边界以外的留给业务系统。第二步,定义隔离模型。批处理是数据隔离、性能隔离、安全隔离,UM 是数据隔离(租户用户数据独立)、权限隔离(租户管理员只能管本租户)。第三步,确定动态扩展机制。批处理是节点动态增减,UM 是无状态认证服务加可水平扩展的会话存储。第四步,建设管理审批流程。服务器管理、数据库授权在 UM 场景中对应租户接入审批、权限模板审批。
复制路径时最忌讳的是把四步做成死流程——每个步骤都要回应该模块的独特性。UM 的独特性在于它处于所有系统的安全边界上,所以认证安全策略(密码策略、登录失败锁定、会话超时)必须是平台级的默认能力。
5.3 六个基础模块的推进节奏:按依赖排序,先做用户再逐步推开
PPT 列出了用户、权限、批处理、报表、内容、日志、监控、事务管理这些基础模块,目标是要实现六个基础模块的平台化。模块之间是有依赖关系的,我的推进建议是:第一优先级做 UM (所有系统都依赖);第二优先级做日志和监控(平台运行的基本可观测性);第三优先级做报表和内容管理;分布式事务管理可以穿插在业务改造过程中。
每个模块的工期预估,参考 Batch PaaS 的经验:需求梳理和边界确认花一到两个月,核心框架搭建两到三个月,业务系统接入适配一两个月,整体周期约半年。六个模块不可能并行推进——团队人数有限,而且并行过深会带来协调成本爆炸。合理的节奏是两条线并行,一条做 UM 加权限,一条继续完善 Batch,每三个月左右交付一个平台能力。
外包开发的边界也要划清楚。PPT 提到了本地实施、外包开发、自主开发三种模式,我的一般判断是:核心框架和隔离模型必须自主开发,这是平台的核心资产;外围管理和审批界面可以外包;IBM BPM、ODM 这类商业产品的实施必须由厂商或资深实施方完成,内部团队承接配置和优化。
6. 验证与复盘:用三个指标确认改造真的达到了 PaaS 标准
改造完成后,光说「上线了」远远不够。我倾向于用三个指标做验收:租户隔离能力、资源供给时效、故障恢复时长。租户隔离能力通过隔离性测试验证,资源供给时效用扩容全流程耗时衡量,故障恢复时长则看节点故障到任务重新调度的秒级数据。
以扩容流程为例,可以写一个简单的验收脚本:
#!/bin/bash # 验证从租户申请节点到任务使用新节点的全流程耗时 start_time=$(date +%s) # 1. 租户发起计算节点申请(模拟调用) curl -X POST http://batch-management/api/tenant/node-apply \ -H "Content-Type: application/json" \ -d '{"tenantId": "demo-tenant", "nodeType": "batch-worker", "cpu": 4, "memory": 8}' sleep 5 # 等待管理员审批(可配置开关,生产建议保留人工审批) # 2. 查询节点注册状态 node_status=$(curl -s http://batch-management/api/node/status?tenantId=demo-tenant) while [[ "$node_status" != *"READY"* ]]; do sleep 5 node_status=$(curl -s http://batch-management/api/node/status?tenantId=demo-tenant) done end_time=$(date +%s) echo "节点从申请到就绪总耗时: $((end_time - start_time)) 秒"这个脚本的验证逻辑:全流程自动化的目标是把节点交付从原来的以天为单位,压缩到分钟级甚至秒级。如果验收时发现流程超过 30 分钟,就要排查卡在哪个环节——通常是审批流程或中间件安装脚本有问题。
故障转移的复盘方法也一样:手动 kill 掉一个 worker 节点上的执行进程,然后观察任务是否在预期时间内被重新调度到存活节点。你会立刻发现很多问题——比如「任务重复执行了」「断点没有续跑」「另一个节点负载瞬间飙高」。这些观察结果才是架构改进的真正输入。
从这套项目里我最大的教训是:PaaS 化改造最容易失败的环节不在技术实现,而在范围蔓延——今天要加一个模块,明天要兼容一种新场景,最终平台变成了一个什么都有但什么都不稳定的巨型系统。所以从那以后,每次启动新的 PaaS 化改造,我都强制列出「这个版本坚决不做的事」,把它贴在需求评审的第一页。平台就得有边界,边界守住了,上面那些模块才能一个一个稳当地长出来。希望这些经验对正在做同类改造的你能有些参考价值。
本文还有配套的精品资源,点击获取