系统设计方案演进(四) 服务高可用实践

235 阅读8分钟

前面讨论过一些高可用的方案了。我们应该如何实用呢?

还是那句话,具体业务具体分析。别人适用的,在你这不一定适用;别人觉得是废案的,在你这说不定用的上。

我们尝试从交易服务的业务出发,来尝试实践一下。实践部分,我计划分两章讲,先讲服务高可用,再讲存储高可用。

一、知彼

这次的设计目标是,日均2000w的支付单。我在某第三方支付公司就职时,这个量曾持续过一段时间,算是比较高的要求。 为什么有选择支付单作为要求基准,这是由压测目标的关注点来决定的。属于业务评估的结果,需要具体场景具体分析。支付场景,肯定是以支付为主。 按照业务分析,2000w的支付单,是指2000w次支付请求,对于支付接口的qps要求,按照二八原则来估算,大约是926qps。

公式:
200000000.8/(2436000.2)92620000000*0.8/(24*3600*0.2)≈926

我们便以1000qps的要求来吧。

二、知己

接下来我们要搞清楚,单个支付应用能在现有硬件资源下,能有什么样的表现。

压力测试!

现有硬件资源,需要掌握的数据如下:
1、应用程序所依赖的云主机或Pod的参数:CPU数量、内存大小、机械硬盘还是SSD
2、应用程序JDK版本、JVM参数配置、垃圾收集器
3、业务数据库参数:mysql版本、CPU、内存、硬盘信息

如果不清楚这些数据,就没有参考意义了。根本不知道我考150分是因为我只有这个能力,还是因为这个试卷只有150分。

1、压测范围

我们回顾下交易服务所处的位置:

业务架构-微服务.drawio.png

交易服务上游系统:
网关 转发http请求至交易服务各个应用

交易服务强依赖系统:
数据库 交易服务自身的业务数据库
商户服务 从商户服务获取商户信息
通道系统 银行组织能力封装,是交易实际处理者
账务系统 账务体系,交易结果的表现者

上下游分析完成后,我们面临一个选择:这次的压力测试,需要全链路压测,还是单应用压测。

全链路压测

将上下游系统全部部署一套压测环境。便于发现业务流程中的短板。

单应用压测

只部署目标应用代码到压测环境,业务强依赖的服务均mock。

一般情况下,在评估某个微服务的极限,不会采用全链路压测。这个时候压测目标是单个微服务自身处理能力。全链路压测是在各服务及对应的存储服务都完成高可用设计并实施后,对整体能力的一个评估。

2、压测流量

压测流量从哪里来呢,大致有两个方案。

真实流量

将生产环境流量复制并导入到压测环境。这样的请求存在天然的多样性,是最佳方案。但是不是每个公司每个团队都有能力获取的。

模拟请求

自行构建请求信息模拟接口请求。这个方案比较务实,由开发同学和测试同学讨论拟定请求场景和请求参数。完全基于参与者对接口的了解程度来制定业务场景,过于主观。

3、压测标准

如上面所说,我们的压测目标是明确单个支付微服务自身处理能力。所以表现上来看,关注的是支付接口在不同压力下的反馈,如响应时间、响应结果等。同时也关注系统表现,CPU利用率,内存占用率,GC健康度等。

如果是单应用压测,不会对其他系统造成影响,可以极限一点,压到接口报错,或系统异常。

最终压测报告,也是表现在指定时间段内,不同qps压力下,接口表现和系统表现的列表。我们选择一个各方面都正常的最高压力程度,来作为支付微服务的极限。

三、节点数分析

知己知彼,得到压测结果之后,则可以进行节点数分析。

经过各方配合和辛苦工作,假设我们得知,支付服务健康极限的qps为40。我们便以这个数据,来决定扩容数量。1000/40=25,我们需要25个支付节点。

根据业务统计,退款订单量约占支付订单的百分之五到百分之十,预计需要3个节点。提现业务量极少,预计1个节点可以支撑。异步通知的业务量,是交易和退款之和,预计需要28个节点。

应用名总需节点数
支付25
退款3
提现1
异步通知28

四、应用单元的设计

到现在为止,我们知道了我们有多少个类型的鸡蛋,接下来,该决定需要几个篮子,以及每个篮子里需要放几个各类型的鸡蛋。

篮子,就是我们需要考虑的应用单元。

1、多个应用单元

需要多少个应用单元,该怎么决定?

第三章中,运维部署的高可用这个环节我们讲过,物理机、机房、地域等,都是可以参考的维度。如果我们的业务还在创业之初,只有一个机房,只是希望隔离物理机故障带来的高可用问题,则可以按照有几个物理机来规划。或者说,我们已经用上了云服务,直接希望按照云服务的归属属性来决定需要做到什么维度的高可用。

总的来说,还是具体部署情况和具体资源投入情况,进行具体分析。但是结果总是一样的,篮子越多,考虑的维度越丰富,出现问题的时候,影响的范围可能会更小。

这个场景,我们只考虑同城三个机房的高可用,那么就设计3个应用单元。

2、应用单元内的微服务配比

把25个鸡蛋,分到3个篮子里,有多少种分法?太多了。我们一般想到的是,均分。

那25个支付微服务节点分到3个应用单元呢?均分也是可以的,每个单元9个支付节点。但是我们还得考虑一下,其他微服务在业务配比上,和支付微服务的关系。

3、应用单元级别的扩容

为什么要有配比,而不是各单元的节点数量之和达到设计节点数量就可以了?

这个是为之后的单元扩容考虑的。单元内的各服务配比决定之后,后续若业务激增,可以直接进行单元扩容,即多部署一个或多个应用单元,来满足业务支撑。

前文提到,退款订单量约占支付订单的百分之五到百分之十。如果支付节点是9个,退款节点1个就够。但是同一个应用单元下,退款节点不能有单节点故障的隐患,所以,最少应该是2个节点。

这么算下来,提现节点需要2个。异步通知节点需要10个。

最终的结果是,3个应用单元,每个应用单元内部署:9个支付节点、2个退款节点、2个提现节点,10个异步通知节点。

应用名每个单元节点数
支付9
退款2
提现2
异步通知10

最终的交易服务部署图示如下:

应用高可用-单元部署.drawio.png

4、收尾

相比节点数分析中的结果,最终方案的节点数要稍微多些,主要是考虑了应用单元内的微服务配比,还要解决应用单元内的单元故障隐患。

当然,这样也做到了冗余。有这些推导数据来支撑,我们的系统能承接多少流量,咱们心里都有底了。

最后

本章我们大致推演了如何通过服务部署到达既定目标的高可用设计,结合压测数据和业务经验来完成微服务的高可用部署,做到知己知彼,心里有底。当然,这些只是架构部署方面的设计,第三章中讨论的代码及业务层面的高可用方案,这里没有一一展开。大家可以自行研究。

接下来,我们将讨论存储层面的高可用实践。