【系统架构】亿级Web 系统的容错性实践【中】

设置超时时间

调用任何一个服务或者存储,一个合理的超时时间(超时时间,就是我们请求一个服务时,等待的最长时间),是非常重要的,而这一点往往比较容易被忽视。通常Web系统和后端服务的通信方式,是同步等待的模式。这种模式,它会带来的问题比较多。

对于服务端,影响比较大的一个问题,就是它会严重影响系统吞吐率。假设,我们一个服务的机器上,启用了100个处理请求的worker,worker的超时时间设置为5秒,1个worker处理1个任务的平均处理耗时是100ms。那么1个work在5秒钟的时间里,能够处理50个用户请求,然而,一旦网络或者服务偶尔异常,响应超时,那么在本次处理的后续整整5秒里,它仅仅处理了1个等待超时的失败任务。一旦比较大概率出现这类型的超时异常,系统的吞吐率就会大面积下降,有可能耗尽所有的worker(资源被占据,全部在等待状态,直到5s超时才释放),最终导致新的请求无worker可用,只能陷入异常状态。


算上网络通信和其他环节的耗时,用户就等待了超过5s时间,最后却获得一个异常的结果,用户的心情通常是崩溃的。

解决这个问题的方式,就是设置一个合理的超时时间。例如,回到上面的的例子,平均处理耗时是100ms,那么我们不如将超时时间从5s下调到500ms。从直观上看,它就解决了吞吐率下降和用户等待过长的问题。然而,这样做本身又比较容易带来新的问题,就是会引起服务的成功率下降。因为平均耗时是100ms,但是,部分业务请求本身耗时比较长,耗时超过500ms也比较多。例如,某个请求服务端耗时600ms才处理完毕,然后这个时候,客户端认为等待超过500ms,已经断开了连接。处理耗时比较长的这类型业务请求会受到比较明显的影响。

解决超时时间过短带来成功率下降问题

超时时间设置过短,会将很多本来处理成功的请求,当做服务超时处理掉,进而引起服务成功率下降。将全部业务服务,以一刀切的方式设置一个超时时间,是比较不可取的。优化的方法,我们分为两个方向。

(1)快慢分离

根据实际的业务维度,区分对待地给各个业务服务配置不同的超时时间,同时,最好也将它们的部署服务也分离出来。例如,天天酷跑的查询服务耗时通常为100ms,那么超时时间我们就设置为1s,某新手游的查询服务通常耗时为700ms,那么我们就设置为5s。这样的话,整体系统的成功率,就不会受到比较大的影响。

(2)解决同步阻塞的

“快慢分离”可以改善系统的同步等待问题但是,对于某些耗时本来就比较长的服务而言,系统的进程/线程资源仍然在同步等待过程中,无法响应其他新的请求,只能阻塞等待,它的资源仍然是被占据,系统的整体吞吐率仍然被大幅度拉低。

解决的思路,当然是利用I/O多路复用,通过异步回调的方式,解决同步等待过程中的资源浪费。AMS的一些核心服务,采用的就是“协程”(又叫“微线程”,简单的说,常规异步程序代码里嵌套比较多层的函数回调,编写复杂。而协程则提供了一种类似写同步代码的方式,来写异步回调程序),以解决同步等待的问题。异步处理的简单描述,就是当进程遇到I/O网络阻塞时,就保留现场,立刻切换去处理下一个业务请求,进程不会因为某个网络等待而停止处理业务,进而,系统吞吐率即使遇到网络等待时间过长的场景,通常都能保持在比较高的水平。

值得补充一点的是,异步处理只是解决系统的吞吐率问题,对于用户的体验问题,并不会有改善,用户需要等待的时间并不会减少。


防重入,防止重复发货

前面我们提到,我们设置了一个比较“合理的超时时间”,简而言之,就是一个比较短的超时时间。而在数据写入的场景,会引起新的问题,就我们的AMS系统而言,就是发货场景。如果是发货请求超时,这个时候,我们需要思考的问题就比较多了。

1、发货等待超时,发货服务执行发货失败。这种场景,问题不大,后续用户重新点击领取按钮,就可以触发下一次重新发货。

2、发货等待超时,发货服务实际在更晚的时候执行发货成功,我们称之为“超时成功”。比较麻烦的场景,则是每次都是发货超时,而实际上都发货成功,如果系统设计不当,有可能导致用户可以无限领取礼包,最终造成活动运营事故。


第二种场景,给我们带来了比较麻烦的问题,如果处理不当,用户再次点击,就触发第多次“额外”发货。

例如,我们假设某个发货服务超时时间设置为6s,用户点击按钮,我们的AMS收到请求后,请求发货服务发货,等待6s后,无响应,我们给用户提示“领取失败”,而实际上发货服务却在第8秒执行发货成功,礼包到了用户的账户上。而用户看见“领取失败”,则又再次点击按钮,最终导致“额外”多发一个礼包给到这个用户。

例子的时序和流程图大致如下:

这里就提到了防重入,简单的说,就是如何确认不管用户点击多少次这个领取按钮,我们都确保结果只有一种预期结果,就是只会给用户发一次礼包,而不引起重复发货。我们的AMS活动运营平台一年上线的活动超过4000个,涉及数以万计的各种类型、不同业务系统的礼包发货,业务通信场景比较复杂。针对不同的业务场景,我们做了不同的解决方案:

1、业务层面限制,设置礼包单用户限量。在发货服务器的源头,设置好一个用户仅能最多获得1个礼包,直接避免重复发放。但是,这种业务限制,并非每个业务场景都通用的,只限于内部具备该限制能力的业务发货系统,并且,有一些礼包本身就可以多次领取的,就不适用了。

2、订单号机制。用户的每一次符合资格的发货请求,都生成一个订单号与之对应,通过它来确保1个订单号,只发货1次。这个方案虽然比较完善,但是,它是依赖于发货服务方配合做“订单号发货状态更新“的,而我们的发货业务方众多,并非每一个都能支持”订单号更新“的场景。

3、 自动重试的异步发货模式。用户点击领取礼包按钮后,Web端直接返回成功,并且提示礼包在30分钟内到账。对于后台,则将该发货录入到发货队列或者存储中,等待发货服务异步发货。因为是异步处理,可以多次执行发货重试操作,直到发货成功为止。同时,异步发货是可以设置一个比较长的超时等待时间,通常不会出现“超时成功”的场景,并且对于前端响应来说,不需要等待后台发货状态的返回。但是,这种模式,会给用户带来比较不好的体验,就是没有实时反馈,无法立刻告诉用户,礼包是否到账。


非订单号的特殊防刷机制

某些特殊的合作场景,我们无法使用双方约定订单号方式,例如一个完全隔离独立的外部发货接口,不能和我们做订单号的约定。基于这种场景,我们AMS专门做了一种防刷的机制,就是通过限制read超时的次数。但是,这种方案并非完美解决重复发货问题,只是能起到够尽可能减少避免被刷的作用。一次网络通信,通常包含:建立连接(connect),写入数据发包(write),等待并且读取回包(read),断开连接(close)。

通常一个发货服务如果出现异常,大多数情况,在connect步骤就是失败或者超时,而如果一个请求走到等待回包(read)时超时,那么发货服务另外一边就有可能发生了“超时但发货成功”的场景。这个时候,我们将read超时的发生次数记录起来,然后提供了一个配置限制次数的能力。假如设置为2次,那么当一个用户第一次领取礼包,遇到read超时,我们就允许它重试,当还遇到第二次read超时,就达到我们之前设置的阀值2,我们就认为它可能发货成功,拒绝用户的第三次领取请求。


这种做法,假设发货服务真的出现很多超时成功,那么用户也最多只能刷到2次礼包(次数可配置),而避免发生礼包无限制被刷的场景。但是,这种方案并不完全可靠,谨慎使用。

在发货场景,还会涉及分布式场景下的CAP(一致性、可用性、分区容错性)问题,不过,我们的系统并非是一个电商服务,大部分的发货并没有强烈的一致性要求。因此,总体而言,我们是弱化了一致性问题(核心服务,通过异步重试的方式,达到最终一致性),以追求可用性和分区容错性的保证。

对于web系统容错机制,还有服务降级、服务解耦等一系列方法将在下篇文章总结。


1. 不用增加任何额外硬件投资,纯软件方式实现双机容错,且对备份机无硬件配置要求。 2. 可支持Notes、Exchange、SQL Server、Sybase、Informix、0racle、SAP等多种系统的应用层叠恢复。 3. 采用全球第一套基于NT操作系统的容错软件,并同时支持UNIX平台。支持远程灾难备份。 4. 支持共享磁盘阵列柜和扩展镜像两种方式,给用户提供了选择上的灵活性,同时也能适应各种机型、网络结构、软件平台及应用系统。 5. 在扩展镜像或共享磁盘阵列任意方式下,均能实现两台NT服务器各自运行不同应用且相互热备份,即实现双机Active运转模式。 6. 使用共享磁盘阵列柜方式时,最多可以支持16个节点,远远大于其它类似系统所支持的2个节点数。 7. 最大限度地保护用户端的应用连续性。用户的硬件资源(如网卡)及软件资源(如NT操作系统、数据库管理系统、数据库应用系统、电子邮件系统等)均能处于该容错系统的保护之下,当这些被保护资源出现技术故障时,容错系统可随时实施系统资源切换。如此,该容错系统真正实现了用户硬件或是软件资源发生故障时系统及应用层上的在线热切换。 8. 占用系统资源极少,不增加网络负荷,且不打扰任何具体应用系统的任何操作。 9. 真正实现无人值守,全自动地实现应用资源切换,且图形界面操作,简单方便。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值