草庐IT

中国人寿业务稳定性保障:“1+1+N” 落地生产全链路压测

TakinTalks稳定性社区 2023-03-28 原文

引言

保险业务的数字化转型正如火如荼地进行,产品线上化、投保线上化、承保线上化、核保线上化等业务转型,导致系统的应用范围不断扩大,用户的高频访问也正在成为常态。同时,系统复杂性也呈指数上升,这些因素都增加了系统的稳定性风险。

中国人寿将无侵入在线压测作为防御稳定性风险的重要手段,作为保险行业首家落地生产全链路压测的企业,其实践经验具有相当的借鉴意义。

作者介绍

中国人寿寿险研发中心高级工程师 熊军军

TakinTalks 稳定性社区专家团成员,毕业于中国科学院自动化所,就职于中国人寿保险股份有限公司研发中心,先后从事产品研发、架构设计、质量管理工作,熟悉保险销售管理及销售支持业务,具备数据治理和高可用架构设计经验。现负责质量中心测试公共能力团队,着力建设质量保障工具及平台,助力提升信息系统稳定性。

温馨提醒:本文约 4800 字,预计花费 9 分钟阅读。

后台回复 “交流” 进入读者交流群;回复“0216”获取课件资料;

背景

作为中国领先的人寿保险公司,中国人寿不断探索新的销售模式转型、加速数字化转型。在数字化应用加深的同时,中国人寿在业务场景、保障手段方面,也逐渐面临较大挑战:

● 从中国人寿寿险业务以往每年的长险出单、学平险的营销活动效果来看,系统在面对高峰流量冲击时的表现,仍有较大改善空间,尤其在容量规划方面;

● 虽在研发流程中有性能测试环节,但更多聚焦在测试环境,而由于生产环境、测试环境的差异性,导致测试环境的压测结果无法精准地还原真实业务状况。生产环境出现性能瓶颈,进而引起用户投诉的情况时有发生;

● 此前中国人寿寿险业务的稳定性保障方式有待加强,原在线压测技术对代码有侵入,不易推广;

针对以上问题,中国人寿寿险研发中心在稳定性保障上做了较多落地实践,在稳定性测试层面,整体思路是在能力层建设 4 种能力——无侵入在线压测能力、混沌工程故障演练能力、自动化测试能力、数字化测试管理能力,来实现保稳定、提质效、优效能的目标。

而其中,保证生产部门稳定是重中之重,无侵入在线压测作为赋能生产部门最重要的手段,我将重点分享其在寿险研发中心落地的经验。

一、无侵入在线压测有哪些建设目标?

1.1 原有压测技术的局限性

在无侵入在线压测落地之前,我们有两类传统的压测手段——测试环境压测、生产环境有侵入压测,而这两种压测都有一定的局限性。

1.1.1 测试环境压测

测试环境压测的主要的问题是测试环境和生产环境不一致,包括:

● 程序不一致

● 配置不一致

● 数据不一致

● 操作人员不一致

1.1.2 生产环境有侵入压测

生产环境的有侵入压测是指生产环境通过修改源代码来识别压测流量,进而正确地路由压测流量,保证压测顺利进行,而不污染生产环境。这个方法的主要影响有三点:

第一是不统一。各系统各自为战,缺乏统一的标准,协作较困难。

第二是技术难共享。技术推广的难度大,导致很难实现全链路在线压测。想要真正了解业务流程的状况,必须对其全链路做测试,否则风险隐患始终存在。隔三差五冒出问题来,这对整个技术团队、业务团队的影响都很大。

第三点是不安全。我们缺乏统一的压测安全管控措施,比如,压测开关一旦出了问题能不能统一关掉?白名单是不是可以控制链路走向?压测前的检查、压测中的资源监控、压缩后的数据检查,都缺乏相应的机制来保障。

1.2 在线压测工作目标:“1+1+N"

无侵入在线压测的工作目标可以用"1+1+N"来概括——1 个平台、1 个流程、N 个场景。

1 个平台——即要建设一个无侵入在线压测平台,能够支持寿险技术中心在对源代码无侵入的前提下开展压测。

1 个流程——由于无侵入在线压测的影响面非常大,关联团队非常多,涉及到开发团队、测试团队、部署团队、生产保障团队、网络组、平台组等等,如果缺乏统一的流程或是职责不清晰,轻则导致工作无法执行,重则将造成生产事故,所以建立统一流程非常必要。

N 个场景——有了平台和流程后,就可以基于此来支持寿险业务 N 个场景的在线压测,比如长险出单、短险出单、培训学习、APP 登录、重大技改等等。比如信创对系统的改造等重大技改,大家非常乐意通过无侵入在线压测的手段,在生产上验证技改前后性能的变化情况,这也是比较重要的应用场景。

二、如何搭建无侵入在线压测“1 个平台”?

2.1 平台简介

无侵入在线压测平台主要包括两个模块,压测任务执行模块和压测链路管理模块。

压测任务执行模块可以理解为一个云化的 JMeter,用来施加压测流量。压测链路管理模块是基于业务应用中的探针,管理被压测的链路,来实现在线压测。

工作原理及主要流程:

绿色箭头所示的压测流量,首先到达业务应用 A,业务应用 A 上的压测探针识别压测流量,然后把它写入到影子库、影子日志、影子 topic(这些影子存储用来存储保存压测数据,并与正式业务数据隔离开),进而把它传递到业务应用 B,业务应用 B 进行业务处理后开始进入到影子库,这样就实现了整体压测流量的路由。走着同样的业务应用通道,但是不影响正式库和正式业务数据,这样就达到了验证正式业务链路性能的目的。

2.2 压测探针

2.2.1 基本原理

压测探针是整个无侵入在线压测的核心部分,其基本原理是基于 Java 字节码技术,它的核心是修改 JVM 中已加载的字节码,在其中加入压测流量处理逻辑,来实现压测流量路由到正确的链路、写入到影子存储。注意,这里不是修改源码,而是修改 JVM 里面已加载的源码,以此来实现对源代码和开发人员的无侵入。既不会造成源代码的互相混淆,也不会因为代码侵入造成更多新的问题。

2.2.2 操作对象

压测的核心目的就是想把压测流量进行路由,让它进入到影子存储,并和正式流量区分开,而流量的路由一般是通过特定的中间件来完成,比如 Tomcat, Redis, Kafka, Oracle 等,所以理论上需要且仅需要增强这些中间件即可,不需要去全面梳理所有业务代码,这就使无侵入在线压测的可行性大幅增加。

下图简要介绍了字节码增强逻辑如何识别压测流量并将该流量路由到压测链路。

2.3 应用管理

业务链路的基本单元是应用,每一个安装了压测探针的应用,都需在压测前做好相关的配置,包括:远程调用的接口,影子库/表,影子消费者,影子日志、缓存、挡板等。

为什么需要做应用配置?举个例子,远程调用的接口,为什么要配置白名单?假设这个应用要调下游的某一个接口,则需要把它配置在白名单里,这是出于安全考虑。因为业务的形式是很复杂的,更换一个投保要素就会到另一条链路了,而另一条链路如果没有安装探针就会出现异常,所以我们通过白名单来确保不走到预期外的链路,进而保障业务安全。同理,配置影子库、影子消费者、影子日志和缓存都有相关的技术考虑,主要是为了将正式数据和业务数据做隔离,挡板部分后面会继续介绍。

2.4 链路管理

我们通常把一个完整的压测链路逐层向下分解为业务流程、业务环节、业务活动、应用,即一个压测链路包括一个或多个业务流程,一个业务流程包括多个业务环节,依此类推。

以中国人寿寿险业务为例,“长险投保”这个业务流程,包含登录、选择产品、填写客户信息、上传投保单、核保、缴费等多个业务环节。其中,“登录”这个业务环节,又包括查询用户状态、校验密码等业务活动。每一个业务活动其实就是一个 API 的调用,每一个 API 的调用对应着一个子链路,如下图所示:

这个子链路涉及多个应用,即一个 API 调用可能涉及多个应用。上面我们已经配置好应用,包括应用相关的存储,这样逐层就能把整个链路串起来,接下来就可以开始进行压测了。

2.5 压测执行

在压测执行的过程中,我们提供了类似阿里 PTS 的全自动化的在线压测能力,可以在线编辑脚本、设置线程组、设置压测参数等。


压测过程中可实时查看整体业务流程、单个业务活动的执行情况,包括 TPS、响应时间、成功率、资源利用率,以及告警和失败请求信息等等。TPS、响应时间、成功率等数据来自压测引擎,资源利用率、告警和失败请求信息则通过压测探针传到监控模块。

测试执行、监控、报告均为自动完成,实现一键完成自动化性能测试。

三、如何设计压测的 “1 个流程”?

3.1 流程简介

首先需要提到的是设计流程的原则,“安全优先、严谨规范、统筹协作”。其中安全优先是第一位,我们在设计任何一个具体技术方案时,永远是考虑安全优先,即使一个更安全的方案会导致工期延长一个月,我们也选择这个方案。

在线压测主要流程步骤包括:方案设计、链路梳理、环境准备、系统配置、链路调试和压测实施等 6 个环节。

3.2 实践难点

3.2.1 难点 1:压测目标设定

压测目标会有什么难度?其实还里面会有一些小技巧。在下图中,黄色的线可以作为历史的峰值承载量,蓝色的线作为本次压测的期望承载能力,比如,某次设定压测的期望峰值是历史峰值的两倍,在链路压测结果出来后,最短板应用所能支撑的吞吐量在红线的位置,它应该高于蓝色的线(期望承载能力)。

那是不是这样就可以保障整个链路没有问题呢?事实并非如此,因为链路上的某个业务环节可能出现拥挤,比如有时登录环节会因为多种业务叠加(包括投保之外的业务)出现登录拥挤,一旦出现这种情况就没有办法开展后续操作了,针对这种情况,就需要单独对登录环节做在线压测,评估一个更高的值来满足要求。所以在线压测的目标有全流程的目标和单环节的目标。

3.2.2 难点 2:影子库创建


在压测过程中,有很大一部分工作量是在影子库上,花费的时间远超预期。主要有两个问题,第一是如何创建影子库,第二是准备多少铺底数据。理想情况当然都是如上图绿色部分,尽量符合实际业务情况,但在条件不具备的情况下,可以考虑用一些折中的办法,比如可以新建一个数据库实例,可以准备一定量级的数据,这个量级可以通过测试环境梯度压测的方法来预先获取。

3.2.3 难点 3:挡板 Mock

挡板有两个作用,第一个作用是屏蔽不希望被执行的业务。比如不希望发送短信,因为发短信这个环节出性能问题的风险较小,所以要把它屏蔽掉,这一块就用入口挡板把它挡掉即可。


第二个作用“执行希望被执行的业务”相对比较难理解,举个例子,保险业务中的影像审核,因为很难构造符合真实情况的影像数据,所以测试业务流转到这个环节,影像审核就会失败,导致后面的环节就无法压测了。此时,在“影像审核”应用出口部分增加挡板,把审核结果改成正确即可解决。这样好处是真实的压测到了影像审核的业务逻辑,验证了该应用模块的性能,同时又不阻断整体压测流程。此外,还需重点关注数据隔离,数据隔离是保障我们压测安全的重要手段。

3.2.4 难点 4:风险预案制定

我们要保障安全压测,必须要做相应的风险预案,例如,对生产系统过载、探针影响正常业务以及业务数据被污染等情况,我们都制定了相应的应急预案,具体如下表。

四、重大业务“N 个场景”保障成效如何?

我认为主要有 3 个成效——

第一是能够准确评估系统容量,做到重大业务活动心中有数。我们在线上实施了 9 次全链路压测,涵盖了长险投保、短险投保、用户登录、签到、学习等等众多业务场景,完成了各场景在生产环境的容量评估。下图,可以准确看到各个场景的最大容量,让我们很有信心地开展重大业务活动。

第二是能够提前发现线上环境问题,保障业务系统稳定运行。通过十多个子团队(含部署)、技术处以及数据中心关联团队的协作,提前识别出生产压测中的性能问题,避免了线上故障引发用户投诉。

(部分链路中识别出的性能问题)

第三是可以真实地开展性能指标对比验证,支持重大技改。下图可以看到,测试前后以及优化前后,性能都有大幅的提升,帮助重大技改后快速度过不稳定期。

公众号后台回复【0216】获取资料

回复【交流】进入读者交流群

声明:本文由公众号「TakinTalks 稳定性社区」联合社区专家撰写,并已获授权整理发布,如需转载,请公众号后台回复“转载”获得授权。

本文由博客一文多发平台 OpenWrite 发布!

有关中国人寿业务稳定性保障:“1+1+N” 落地生产全链路压测的更多相关文章

  1. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  2. ruby-on-rails - Ruby 和 SQL 中的重复业务逻辑 - 2

    我有一个PORO(普通旧Ruby对象)来处理一些业务逻辑。它接收一个ActiveRecord对象并对其进行分类。为了简单起见,以下面为例:classClassificatorSTATES={1=>"Positive",2=>"Neutral",3=>"Negative"}definitializer(item)@item=itemenddefnameSTATES.fetch(state_id)endprivatedefstate_idreturn1if@item.value>0return2if@item.value==0return3if@item.value但是,我还想根据这些st

  3. ruby - 如何进行稳定排序? - 2

    如何稳定地对数组进行排序?我要排序的值可能有很多重复项,我不确定ruby​​使用哪种排序算法。我认为插入排序最适合我。示例:a=[[:a,0],[:b,1],[:c,0],[:d,0]]a.sort_by{|x,y|y}#=>[[:a,0],[:d,0],[:c,0],[:b,1]]寻找[[:a,0],[:c,0],[:d,0],[:b,1]] 最佳答案 把你原本想排序的键和索引放到一个数组中,然后排序。a.sort_by.with_index{|(x,y),i|[y,i]}#=>[[:a,0],[:c,0],[:d,0],[:b,

  4. Nature Neuroscience:高家红团队首次发布中国人脑连接组计划研究成果及其大数据资源 - 2

    人类生活在充满多样性的世界里。长久以来的研究发现,人类的脑与行为受到基因、环境和文化及其相互作用的塑造,然而这种影响发生的机制始终缺乏系统性探索与研究。近年来,前沿神经影像技术方法飞速进步,推动着多模态脑成像大数据集的产生和融合性探索,并让学界得以深入探究人脑宏观结构与功能连接组架构,为包括上述主题在内的许多有趣而重要的科学问题带来了新的启发和思路。2022年12月20日,北京大学物理学院、IDG麦戈文脑科学研究所高家红团队在《NatureNeuroscience》在线发表了题为“IncreasingdiversityinconnectomicswiththeChineseHumanConne

  5. 中国民用飞机制造行业市场现状规模及发展战略规划报告2021-2027年 - 2

    中国民用飞机制造行业市场现状规模及发展战略规划报告2021-2027年详情内容请咨询鸿晟信合研究院!【全新修订】:2022年2月【撰写单位】:鸿晟信合研究研究【报告目录】第1章:中国民用飞机制造行业发展综述1.1民用飞机制造行业概述1.1.1民用飞机的概念1.1.2飞机制造的概念1.1.3民用飞机的分类1.2民机制造行业周期特性1.2.1影响行业周期的因素(1)GDP增速分析(2)运量增量分析(3)飞机更替分析(4)航空公司获利水平1.2.2行业现阶段周期分析1.2.3行业现阶段景气分析1.3民机制造信息化分析1.3.1信息化技术应用状况分析(1)MDO技术应用分析(2)供应链协同研发分析(3

  6. ruby - RobuSTLy 调用不稳定的 API:使用 Net::HTTP 进行正确的错误处理 - 2

    我将其组合在一起,作为一种看似可靠的方式来调用不稳定的Web服务,该服务会出现超时和偶尔的名称解析或套接字错误或其他任何问题。我想我会把它放在这里以防它有用,或者更有可能被告知执行此操作的更好方法。require'net/http'retries=5beginurl=URI.parse('http://api.flakywebservice.com')http=Net::HTTP.new(url.host,url.port)http.read_timeout=600#beverypatientres=nilhttp.start{|http|req=Net::HTTP::Post.new

  7. ruby-on-rails - 是否有任何示例 Rails 应用程序将业务逻辑保存在与 ActiveRecord 不同的类中? - 2

    Ruby社区最近出现了大量关于使用更好的OO设计的好处的博客文章、推文和评论,特别是将业务逻辑与持久性逻辑分开。特别是对于较大的应用程序,我认为这是很好的建议。http://solnic.eu/2011/08/01/making-activerecord-models-thin.htmlhttp://blog.steveklabnik.com/2011/09/06/the-secret-to-rails-oo-design.htmlhttp://avdi.org/devblog/2011/11/15/early-access-beta-of-objects-on-rails-now-a

  8. ruby - 使用 rbenv 安装最新稳定版本的 Ruby - 2

    我想安装可用的最新稳定版Rubyrbenv.此功能won'tbehappening在rbenv本身。当我在我的shell中运行命令rbenvinstall-l时,我得到了一长串可用版本。该列表包含所有类型的条目。以下是展示格式和多样性的部分列表:$rbenvinstall-lAvailableversions:2.0.0-p6432.0.0-p6452.1.0-dev2.1.0-preview12.1.0-preview22.1.0-rc12.1.42.1.52.1.62.2.0-dev2.2.0-preview12.2.0-preview22.2.0-rc12.2.02.2.12.2

  9. Jmeter安装压测相关插件以及压测示例(含图表展示) - 2

    开始正文前需要先了解一下Jmeter线程组配置的含义,方便后面示例了解 一、压测相关插件安装1、下载jmeter-plugins-manager-1.7.jar(或者别的版本也可以),然后放到jmeter文件下的lib\ext目录中,然后启动jMeter2、在选项中选择pluginsmanager,再勾选3BasicGraphs,5AdditionalGraphs,Distribution/PercentileGraphs,KPIvaKPIGraphs,PerfMon,CustomThreadGroups。其他自己往下找就能找到3、添加性能监听指标(监听器中找一下)(1).bytesthrou

  10. ruby - Ruby 中的排序稳定吗? - 2

    Ruby中的sort稳定吗?也就是说,对于sort并列的元素,它们之间的相对顺序是否保留了原始顺序?例如,给定:a=[{id::a,int:3},{id::b,int:1},{id::c,int:2},{id::d,int:0},{id::e,int:1},{id::f,int:0},{id::g,int:1},{id::h,int:2},]是否保证我们总能得到a.sort_by{|h|h[:int]}以下[{id::d,int:0},{id::f,int:0},{id::b,int:1},{id::e,int:1},{id::g,int:1},{id::c,int:2},{id::h

随机推荐