中国保险万事通与2018-07-08日正式上线,历经三年精心组织、持续优化,为消费者打造了一个贯穿保险全链条的公益性服务平台。涵盖六类功能、十个模块,贯穿保险需求诊断、产品筛选、产品咨询、保单管理、理赔咨询、投诉咨询、知识教育七大环节。
该系统具有五大特色功能:
我作为其中的一家保险公司,参与了第一个功能的对接工作:消费者保单统一查询通道。万事通首次在全国范围内为消费者提供集中的线上保单查询通道。该通道通过采用金融行业最为严格的四要素(姓名、×××、手机、人脸识别)认证,在确保用户隐私的情况下,实现保单一键查询。
其实这个需求非常简单,保险公司把每日产生的新的客户的证件号同步给保协,保协根据用户的身份信息判断是那个保险公司的保单,然后调用保险公司的接口查询保单信息。
在接收到需求后我们2个月左右已经开发测试完成,并且和保协进行了联调测试。从测试的结果看单个请求都可以在3秒内返回。我们初始的系统架构如下,用户查询保单后,先经过我们的前置(前置什么事情都不干,只做转发和报文存储,只有前置有外网的访问权限),然后进入我们的后置服务器(进行报文解析,业务规则处理),后置服务器接收到请求后请求核心,返回返回相应的查询结果,在返回给保协。
在我们觉得这个项目就要完成的时候,保协为了程序的稳定性需要进行压力测试,测试的指标如下:
标准是
并发数100,请求数:240000(总请求数)
允许失败的请求数:最多允许2400
业务解析正确的请求数:至少237600
平均响应时长/ms:小于3000(所有的请求响应均应小于3000ms)
并发100的情况下,坚持两小时,则100*60*60*2/3(最大响应时长)=24W
在接收到这个压测标准后,我们使用了LoadRunner进行了压力测试,压力测试的结果如下:
先跑了一个小时:
我们测试了一个小时,平均的响应时间在2.9秒,而且还是内网的。这离标准还差的很远,然后我们进一步分析了到底是网络原因还是服务的原因
我们发现并发量小的时候主要消耗在网络上,并发量大时主要消耗在后台服务上。我们首先猜测是不是服务器配置的最大线程数量不够,并发量大的时候线程一直处于等待的状态,导致响应速度比较慢。我们对服务器的参数做了如下调整:
(1).把jboss等待线程上调为550,执行线程上调为150.
(2). 调整了nginx的 worker_connections。
调整后,重新测试了下,这一次压测在100并发的情况下跑了两个半小时,平均速度要3.247。还是没有达到我们预期的结果
现有的程序已经无法满足压测需求,为了达到压力测试的标准,我们提出了如下几种解决方案:
1)升级网络带宽,升级服务器硬件(提高CPU和内存)
压力测试100并发,响应时间3秒推荐配置:
一台nginx转发机,配置:内存3G,硬盘:37G 4核CPU CPU:Intel(R) Xeon(R) CPU E7- 4830 @ 2.13GHz
五台负载机,配置:内存4G,硬盘:37G 4核CPU CPU:Intel(R) Xeon(R) CPU E7- 4830 @ 2.13GHz
10M带宽
2)升级DB服务器,数据落到SSD磁盘上
3)请把每天需要的数据提前计算好,并单独落到DB中存储,不要通过各种 join 查询,从其他表实时获取数据。
根据项目现有的情况对上面的三种方案的可行性进行了分析。第一,二种解决方案虽然可以减少开发量,但是需要单独为这个需求去申请硬件资源,增加了相应的成本,所以就直接pass掉了。这里我们采用了第三种解决方案,这种解决方案的思路就是异步化。
我们对现有系统的架构做了如下调整:
1. 核心系统T日同步T-1日的保单数据,保单数据按照保协要求的格式封装好。然后通过批处理的方式把这些数据保存到我们中间平台。用户查询保单信息的时候,我们直接返回,不在实时请求我们的核心系统。每日凌晨同步的数据如下:
2. 由于我们原有的系统架构要求保存每个交易的请求,返回报文及保存相应的操作记录,方便后续调查相应的问题。这里面涉及到IO的操作及数据库的插入操作。针对这种情况我们引入了Redis,先把这些存入到Redis中,在服务器空闲的时候比如凌晨从Redis获取出来,然后在保存到数据库中。请求及返回报文通过每日凌晨批出里从Redis中获取然后存入到相应的目录中,减少了实时请求的IO操作
交易记录也通过批处理的方式插入到数据库中:
3. 批处理的配置如下:
系统通过改造后,数据库的插入及IO相关的操作基本上都通过异步的方式进行处理了,当前只剩下查询的操作。我们对查询操作进一步进行了优化,在表中添加了相应的索引。一切准备就绪后,我们内部先进行了压力测试,压力测试的结果是:1.068秒,效果还是很明显的。
然后我们提交到保协压力测试,测试的结果如下。平均响应时长883 [ms]。这个时间之所以比我们压测的时间还要快,是因为这个直接在生产做的压力测试,生产环境的服务器配置比测试环高
返回信息
======================================================
保单验真二期验真接口压力测试报告
报文长度 : 495 bytes
并发量 : 100
测试总时长: 2134
成功的请求数 : 240000
失败的请求数 : 0
业务解析正确的请求数: 240000
累计传输数据量/byte : 471556000 bytes
累计传输的业务数据量/byte : 437264000 bytes
平均每秒请求数 : 112 [#/sec] [mean]
平均响应时长/ms : 883 [ms] [mean]
传输速率 KB/s : 215 [KB/s] [mean]
请求响应时长分布 (ms):
1% 395
2% 491
3% 518
4% 540
5% 562
6% 585
7% 607
8% 626
9% 640
10% 651
11% 659
12% 666
13% 672
14% 677
15% 683
16% 688
17% 692
18% 697
19% 702
20% 708
21% 713
22% 718
23% 724
24% 731
25% 737
26% 744
27% 751
28% 758
29% 765
30% 771
31% 778
32% 784
33% 790
34% 796
35% 801
36% 807
37% 812
38% 816
39% 820
40% 824
41% 828
42% 832
43% 836
44% 839
45% 843
46% 846
47% 850
48% 853
49% 857
50% 860
51% 864
52% 867
53% 871
54% 875
55% 879
56% 884
57% 889
58% 893
59% 899
60% 904
61% 910
62% 916
63% 922
64% 928
65% 934
66% 940
67% 946
68% 952
69% 958
70% 963
71% 969
72% 974
73% 979
74% 984
75% 989
76% 994
77% 998
78% 1003
79% 1008
80% 1014
81% 1019
82% 1025
83% 1031
84% 1039
85% 1048
86% 1058
87% 1070
88% 1084
89% 1099
90% 1116
91% 1131
92% 1148
93% 1165
94% 1184
95% 1212
96% 1294
97% 1366
98% 1544
99% 1909
======================================================
压测结果:通过;
从接收到需求到压测通过,历时大半年的时间。由于之前没有这方面的经验,在选用第三种解决方案之前大量测尝试,才能保证该方案可以一次性测试通过。
尝试如下:
(1).我们系统的外网是电信的,保协是联通。我们让网络的同事给了联通的IP进行过外网的测试,但是没有达压力测试的标准。
(2). 把我们的程序发布到北京腾讯云服务器,让保协直接同城访问,这样虽然达到了测试的要求,但是不符合我们部署的规则,所以无法采用该方案。该方案说明网络在压力测试中的影响还是蛮大的。
(3).在不改变网络和硬件服务器的基础上,把程序中与数据库及IO的操作先删除,采用固定变量写死的方式,查询的时候直接返回一个常量字符串。该方案测试后符合压力测试的标准,这也是我们为什么会采用第三种方案的原因。
在压力测的过程中我们也遇到过如下问题:
(1). 程序中使用了全局变量,由于是高并发的,所以有些刚刚加密完成就被下一个请求给替换了,所以返回了明文.
(2).程序中使用了springmvc,struts这些mvc框架的,压测可能接收不到中保协加密后的报文体。修改为 注解@RequestBody 可以获取request中数据,具体可参考如下两篇文章
http://blog.csdn.net/tianhongqiang/article/details/51636413
http://www.it610.com/article/966404.htm
(3). 压力测试以后,SFTP连接的时候保错,错误信息为:too many open files。我们排查了一下程序,是我们程序有个公共模块的输入流及输出流没有关闭,由于之前没有测试过这么大的并发量,所以之前没有发现。修改程序,重启服务器后恢复正常。
相应的问题可参考这篇文章:http://www.51testing.com/html/71/410671-819286.html
这个需求经历的大半年的时间,从中也学习到很多。最后总结一句话就是:好的架构不是设计出来的而是不断的演进而来的。解决大并发的思路为:异步!异步!异步!重要的事情说三遍。