ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

保险核心系统上云实践:批处理PaaS化改造与并行计算模型

保险核心系统上云实践:批处理PaaS化改造与并行计算模型 简介这份PDF是农银人寿新一代核心业务系统云平台实践报告面向保险行业IT决策者、架构师与云计算实施团队剖析传统金融机构如何将云技术落地解决技术陈旧、扩展困难等现实问题。资源为单份PDF文件共2.64MB由作者sysocc上传已有622人浏览学习。内容涵盖项目背景、新核心系统的云平台总体设计以及批处理平台Batch PaaS、用户管理UM PaaS两大实例重点展示了多租户隔离、虚拟机动态分配、故障自动转移等关键改造思路并给出基于既有软硬件资产的务实实施路径。读者可由此了解从传统核心系统向云架构迁移的完整过程掌握PaaS化改造中的架构取舍与落地细节适合作为保险业云平台建设的参考范例。1. 传统险企核心系统上云为什么第一个吃螃蟹的是批处理传统保险公司做云平台最常见的失败不是技术选型翻车而是把“上云”当成一次性的系统替换。农银人寿这个案例有意思的地方在于他们没有试图一夜间把核心系统搬进私有云而是先从批处理平台Batch PaaS开刀。旧核心系统基于 JDK 1.4.2 和 JSPServlet跑批慢、不定期宕机、紧急补丁多但每年业务增长超过 50%IT 响应速度已经脱节。在这种资源有限、架构老化的背景下批处理成为最适合“PaaS 化”的切入点它的负载特征清晰、边界明确、改造成果可以用跑批时长直接量化。这篇文章会顺着他们的云平台分层、批处理并行模型、多租户改造和动态资源分配一条线拆开讲最后落到可复现的排错和验证手段上。适合正在做遗留系统上云、私有云建设或 PaaS 组件规划的读者参考。2. 新一代核心云平台IaaS/PaaS 分层与选型约束2.1 从“全部上云”到“私有云优先”的落地方案云平台落地第一个要回答的问题不是用 OpenStack 还是 VMware而是业务边界放在哪。农银人寿的规划里公有云、私有云、混合云都出现了但近期实施原则很明确私有云优先混合云作为远期规划。这个选择很现实保险核心系统涉及大量客户保单、财务、渠道数据公有云的合规审批和数据出域问题短期内难以打通而 VMware 虚拟化加 Oracle 12C 加 WebLogic 12C 的组合已经在公司存在多年直接升级成 IaaS 层能最大程度保留现有运维团队的知识技能。操作上我一般会先对现有物理机和虚拟化环境做一轮资产盘点把跑批节点、数据库节点、接口机按 CPU、内存、存储占用分类再决定哪些资源适合被新平台纳管。不要一上来就割接全部业务先把批处理这类无状态、可水平扩展的应用节点迁到新 IaaS验证动态创建、回收和监控链路通畅后再逐步扩大范围。这样做法的好处是每一个步骤都有明确的回退边界不会因为一次上云失败造成核心业务停摆。2.2 PaaS 能力地图流程、规则、内容、监控、分布式事务PaaS 层是这套云平台的核心。原文列出了 10 个左右的组件按现有材料整理如下分类组件选型方式主要职责流程管理IBM BPM商业产品本地实施业务流程编排与可视化规则管理IBM ODM商业产品本地实施保险产品规则、核保规则集中管理内容管理ECM商业产品加自定义保单、影像、合同等非结构化内容存储监控平台MONITA自建运行状态监控、告警与日志分析分布式事务管理DTX自建跨系统分布式事务一致性协调用户管理UM自建统一认证、权限和租户管理批处理平台Batch合作厂商产品二次开发大批量数据并行计算报表平台Report商业产品经营报表、监管报表生成渠道接入平台CIPS商业产品移动端、柜面、第三方渠道的统一接入这些组件的选择不是随意的。保险业务最容易变化的是渠道、产品、规则、流程、销管基本法五个要素PaaS 的定位是让 80% 的应用开发不再重复处理这些基础设施。流程管理和规则管理选了 IBM 的商业产品因为规则引擎和流程编排在金融领域已经有成熟的实现模型自研的维护成本会远高于购买成本。而用户管理和批处理这种与业务组织架构、运行负载强相关的部分商业产品往往太重且封闭所以选择了自主开发。2.3 选型约束商业产品、外包开发与现有资产复用这版云平台有一个值得注意的原则充分利用遗留应用系统、已购软硬件资产、现有人员知识技能。很多传统企业上云喜欢推倒重来结果发现迁移成本比新建还高。农银人寿的做法是让新平台继承旧资产比如仍使用 Oracle 12C 和 WebLogic 12C而不是强行替换成开源中间件。这样数据库和中间件的运维经验可以直接复用Oracle RAC 的高可用能力也能平滑平移。实施模式上商业产品本地实施为主外包开发为辅开源产品自主开发目前是零。这个比例在传统保险行业很典型商业产品能兜底外包解决短周期人力缺口而开源产品因为没有本地专家长期维护反而容易变成风险点。如果你也面临类似的资源约束我的建议是先列出核心能力清单逐个评估商业产品覆盖度只在商业产品覆盖不到的缝隙里自建。批处理和用户管理就是这样的缝隙它们业务差异大市场上没有能直接套用的通用 PaaS 产品。3. Batch PaaS 并行计算模型Job/Task/Executor 的一次拆解3.1 原有批处理开发模式为什么慢老批处理是一个 Job 从头跑到尾中间虽然有多个 Task但基本是顺序执行数据量一大就变成纯等待。而且 Job 内访问什么数据库、在哪台机器跑都是程序写死的扩容等于重新开发。这样的架构下跑一次分红批处理要数小时新增业务节点也无法让任务变快因为任务根本没有拆分。改造的目标是让批处理具备并行计算能力。核心思路是一个 Job 根据数据量拆成多份 Task由 Distributor 分发到多个 Executor 并行执行。每一份 Task 处理一个数据分片比如按客户号范围、保单号取模或者日期段。分片之间没有依赖关系才能真正得到线性扩展效果。原项目里提到的五个基本概念Job、Task、Distributor、Executor、SharedResourceHolder就是这套并行模型的落地骨架。3.2 Job 拆分与 Executor 实现的关键类按原项目说明开发人员需要理解五个基本概念其中要具体实现后面三个的子类。这里给一个最简可跑的示例骨架说明每个类要承担什么职责。public abstract class BaseDistributorT extends TaskConfig { public final ListT split(JobContext ctx) { int taskCount resolveTaskCount(ctx); ListT tasks new ArrayList(taskCount); for (int i 0; i taskCount; i) { T cfg createTaskConfig(); cfg.setJobId(ctx.getJobId()); cfg.setShardIndex(i); cfg.setShardTotal(taskCount); tasks.add(cfg); } return tasks; } protected abstract T createTaskConfig(); protected abstract int resolveTaskCount(JobContext ctx); }split 方法根据 JobContext 里的参数确定要拆多少份 Task。taskCount 不是越大越好建议按集群总计算能力的 2 倍左右设置避免任务排队时间过长。createTaskConfig 里会带上 shardIndex 和 shardTotalExecutor 拿到这两个值后就能算出自己该处理哪一段数据。public abstract class BaseExecutor { public final TaskResult handle(TaskConfig cfg) { try { SharedResourceHolder holder SharedResourceHolder.getInstance(); DataSource ds holder.getDataSource(cfg.getDsName()); logger.info(shard {}/{} start on {}, cfg.getShardIndex(), cfg.getShardTotal(), getNodeName()); return doTask(cfg, ds); } catch (Exception e) { return TaskResult.fail(cfg.getShardIndex(), e); } } protected abstract TaskResult doTask(TaskConfig cfg, DataSource ds) throws Exception; }Executor 是实际执行逻辑的类。handle 方法先拿到共享资源再调 doTaskdoTask 里按 shardIndex 计算 SQL 查询范围例如where mod(customer_id, #{shardTotal}) #{shardIndex}。这样每个 Executor 处理的数据互不重叠而且天然支持动态扩容新增节点后把 taskCount 调大重新分发即可。要注意的是不要在 doTask 里自行创建线程池否则每个分片内部还会再拆线程最终导致任务并发数不可控。3.3 SharedResourceHolder 与 Java 内存参数设置SharedResourceHolder 的职责是集中管理数据库连接池、缓存连接池和 Spring 上下文。批处理场景里如果每个 Task 都自行创建连接池节点一多就可能打满数据库连接数。public class SharedResourceHolder { private static final SharedResourceHolder INSTANCE new SharedResourceHolder(); private final ConcurrentHashMapString, DataSource pools new ConcurrentHashMap(); public DataSource getDataSource(String dsName) { return pools.computeIfAbsent(dsName, this::createDataSource); } private DataSource createDataSource(String dsName) { HikariConfig config new HikariConfig(); config.setMaximumPoolSize(getPoolSize(dsName)); config.setJdbcUrl(resolveJdbcUrl(dsName)); return new HikariDataSource(config); } }逻辑说明computeIfAbsent 保证同一个数据源在进程内只初始化一次。连接池大小建议结合批处理单节点并发线程数来配不要盲目用默认值。如果 Executor 有 16 个线程HikariCP 的 maximumPoolSize 设成 16 或稍大一点即可太多反而造成数据库端线程切换和锁等待。ZooKeeper 在这个平台里负责节点注册和故障转移。开发阶段容易遇到的一个坑是 ZooKeeper 会话超时设置过短网络一抖动 Executor 就被判定为失联然后任务被重新分发造成重复执行。建议把 zk.sessionTimeout 设在 10 到 30 秒之间批处理对一致性要求高于实时性可以放宽到 30 秒。参考参数如下参数推荐值设置依据taskCount节点数 × CPU 核数 × 2保证每个 CPU 都有任务可跑executor.threadsCPU 核数 ~ 2×核数过高会增加上下文切换zk.sessionTimeout10s ~ 30s平衡故障检测精度与误判率hikari.maximumPoolSize等于 Executor 线程数避免连接被占用空转4. 多租户与动态资源分配把批处理改造成 PaaS 的核心改造点4.1 多租户隔离数据、性能、安全三维度原批处理系统没有多租户概念所有用户都能查看和管理所有批处理任务自动分发到所有服务器执行数据库地址由程序自行设定。在企业内部自用时这些问题不明显一旦要对多个业务线或外部机构提供 PaaS 能力安全漏洞和资源争抢就会暴露出来。改造后的多租户模型要求三个隔离隔离维度原系统新系统数据隔离程序自行连接任意库每个租户只能访问授权数据库性能隔离任务在所有节点上混跑任务绑定租户专属计算节点安全隔离所有用户共享可见性用户只看得到和管理自己的批处理原文特别强调“不只是在数据库中增加一个区分租户的字段”。我理解这是指租户隔离要从资源层开始做而不是只靠 SQL 加 where 条件。批处理场景下如果不同租户的任务混在同一批节点上一个租户的大任务会占满 CPU 和 IO另一个租户即使数据量小也会被拖慢。所以更可靠的做法是给高优先级租户固定分配节点普通租户共享同一个资源池再通过队列权重控制资源配额。4.2 服务器动态分配从申请到 VMware 自动交付动态分配是让批处理平台从固定集群变成可弹性 PaaS 的关键。原系统里增加资源要走采购流程新系统里用户申请计算节点后管理员审批系统自动调用 VMware API 创建虚机批处理管理员授权后用户的 Job 即可使用新节点。整体流程可以用下面几个步骤概括用户在前端提交计算节点申请填写租户标识、所需 CPU 和内存。虚机管理员审批申请系统调用 VMware 接口创建虚机。虚机启动后批处理 Agent 自动注册到 ZooKeeper。批处理管理员把新节点授权给指定租户。用户的后续 Job 可以被调度到新节点执行。这里以 VMware PowerCLI 为例展示自动创建虚机的常见做法Connect-VIServer -Server vc.example.com -User svc_provision -Password ****** $template Get-Template -Name batch-node-tpl $nodeName batchnode- $tenantId - (Get-Random -Maximum 9999) New-VM -Name $nodeName -Template $template -Datastore DS01 -VMHost host-prod01 Start-VM -VM $nodeName Write-Host Node $nodeName provisioned参数说明batch-node-tpl 是预装了 JDK、Batch Agent、ZooKeeper 客户端的基础模板tenantId 是租户标识保证节点归属清晰。New-VM 指定 datastore 和 VMHost 是为了让新节点落在有计算冗余的宿主机上。虚机启动后Batch Agent 会自动注册到 ZooKeeper 的/batch/nodes目录Distributor 扫描到新节点后即可派发 Task整个过程不需要人工改配置文件。我一般会在自动化脚本里加一段健康检查等待 Agent 注册成功后再返回创建成功。否则用户看到节点已经开机但调度器还没有感知就会误以为系统故障。4.3 对照原系统的改造边界与未完成项这个案例里明确提到了未完成项Oracle DB 和 WebLogic 的动态分配没有实现。原因是数据库是有状态服务动态创建后涉及网络地址、实例名、数据初始化、回切等一系列问题比无状态计算节点复杂得多。WebLogic 也是类似域配置、集群配置和连接池绑定比虚机创建更敏感。所以实际落地时动态分配要分阶段先做无状态的计算节点弹缩再逐步尝试中间件层最后才是数据库层。如果一上来就想全链路动态化很可能被状态一致性拖住几个季度都上不了线。这个边界意识反而让项目更快落地。多租户方案里也要为数据库层预留扩展点例如把租户和数据库实例的映射表独立维护后续接上动态分配时不用改太多代码。5. 用户管理UM PaaS与云上批处理落地的排错复盘5.1 UM PaaS 在云平台里的定位用户管理UM PaaS和批处理平台一样属于 PaaS 里的基础服务。它解决的问题是多个业务系统共用同一套用户、组织和权限模型而不是每个应用单独建表。常见做法是统一的 RBAC 模型通过 OAuth2 或 CAS 提供单点登录用户表、角色表、权限表都和租户 ID 绑定。对批处理平台来说UM 的权限模型决定了用户能操作哪些 Job、申请哪些节点、访问哪些数据源。在实践里UM 建议把逻辑删除和审计字段都带上比如operator_id、tenant_id、created_at。因为云平台上的权限变更需要能追踪否则多租户环境下出了越权问题很难定位。5.2 用 ZooKeeper 验证动态扩容是否生效动态分配节点后第一件事是验证节点真的加入了批处理集群而不仅仅是虚拟化平台里显示开机。在管理机上查看 ZooKeeper 节点列表/opt/zookeeper/bin/zkCli.sh -server zk01:2181 ls /batch/nodes命令输出会列出当前所有在线计算节点的主机名。比对刚创建的虚机名确认已出现。如果没出现重点看 Agent 日志里 ZooKeeper 地址是否可达、sessionTimeout 是否设置得太小导致反复重连以及 Java 版本是否和模板一致。再进一步可以提交一个空转测试 Job控制 taskCount1观察 Distributor 是否把任务派发到新节点。执行成功后新节点的 Executor 日志里会出现shard 0/1 start的记录。这一步验证的是端到端调度链路比只看注册列表更可靠。5.3 排查批处理卡死的三个入口批处理跑得慢或者卡住时我通常从三个入口排查。第一看 ZooKeeper 节点列表有没有 Executor 掉线掉线会导致任务一直等不到执行者第二看数据库连接池监控HikariCP 的 active 线程数是否打满如果打满且没有等待队列说明 SQL 效率或行锁有问题第三看 Executor 线程栈是否存在分布式事务等待超时或分片键计算不均。这三个入口分别对应平台层、数据层和应用层从外到内逐层排除比盲目调大 taskCount 有效得多。本文还有配套的精品资源点击获取
返回列表