ZERO TO ONE |「付钱拉」支付系统架构系列二:如何提高应用的可用性(上篇)

对于互联网应用和企业大型应用而言,多数都尽可能地要求做到7*24小时不间断运行,而要做到完全的不间断运行可以说“难于上青天”。

为此,对应用的可用性程度一般衡量标准有三个9到五个9。



对于一个功能和数据量不断增加的应用,要保持比较高的可用性并非易事。为了实现高可用,「付钱拉」 从避免单点故障、保证应用自身的高可用、解决交易量增长等方面做了许多探索和实践。

在不考虑外部依赖系统突发故障,如网络问题、三方支付和银行的大面积不可用等情况下,「付钱拉」的服务能力可以达到99.999%。

本文重点讨论如何提高应用自身的可用性,关于如何避免单点故障和解决交易量增长问题会在其他系列讨论。

为了提高应用的可用性,首先要做的就是尽可能避免应用出现故障,但要完全做到不出故障是不可能的。互联网是个容易产生“蝴蝶效应”的地方,任何一个看似很小的、发生概率为0的事故都可能出现,然后被无限放大。

大家都知道RabbitMQ本身是非常稳定可靠的,「付钱拉」最开始也一直在使用单点RabbitMQ,并且从未出现运行故障,所以大家在心理上都认为这个东西不太可能出问题。

直到某天,这台节点所在的物理主机硬件因为年久失修坏掉了,当时这台RabbitMQ就无法提供服务,导致系统服务瞬间不可用。

故障发生了也不可怕,最重要的是及时发现并解决故障。「付钱拉」对自身系统的要求是,秒级发现故障,快速诊断和解决故障,从而降低故障带来的负面影响。

首先我们简单的回顾一下,「付钱拉」曾经碰到的一些问题:

以史为鉴

1

新来的开发同事在处理新接入的三方通道时,由于经验不足忽视了设置超时时间的重要性。就是这样一个小小的细节,导致这个三方队列所在的交易全部堵塞,同时影响到其他通道的交易。

2

「付钱拉」系统是分布式部署的,并且支持灰度发布,所以环境和部署模块非常多而且复杂。某次增加了一个新模块,由于存在多个环境,且每个环境都是双节点,新模块上线后导致数据库的连接数不够用,从而影响其他模块功能。

3

同样是超时问题,一个三方的超时,导致耗尽了当前所配置的所有worker threads, 以至于其他交易没有可处理的线程。

4

A三方同时提供鉴权,支付等接口,其中一个接口因为「付钱拉」交易量突增,从而触发A三方在网络运营商那边的DDoS限制。通常机房的出口IP都是固定的,从而被网络运营商误认为是来自这个出口IP的交易是流量攻击,最终导致A三方鉴权和支付接口同时不可用。

5

再说一个数据库的问题,同样是因为「付钱拉」交易量突增引发的。建立序列的同事给某个序列的上限是999,999,999,但数据库存的这个字段长度是32位,当交易量小的时候,系统产生的值和字段32位是匹配的,序列不会升位。可是随着交易量的增加,序列不知不觉的升位数了,结果导致32位就不够存放。类似这样的问题对于互联网系统非常常见,并且具有隐蔽性,所以如何避免就显得非常重要了。

◆◆◆◆

下面我们从三个方面来看「付钱拉」所做的改变。

(一)尽可能避免故障

设计可容错的系统

比如重路由,对于用户支付来说,用户并不关心自己的钱具体是从哪个通道支付出去的,用户只关心成功与否。「付钱拉」连接30多个通道,有可能A通道支付不成功,这个时候就需要动态重路由到B或者C通道,这样就可以通过系统重路由避免用户支付失败,实现支付容错。


还有针对OOM做容错,像Tomcat一样。系统内存总有发生用尽的情况,如果一开始就对应用本身预留一些内存,当系统发生OOM的时候,就可以catch住这个异常,从而避免这次OOM。

某些环节快速失败“fail fast原则”

Fail fast原则是当主流程的任何一步出现问题的时候,应该快速合理地结束整个流程,而不是等到出现负面影响才处理。

举个几个例子:

1-「付钱拉」启动的时候需要加载一些队列信息和配置信息到缓存,如果加载失败或者队列配置不正确,会造成请求处理过程的失败,对此最佳的处理方式是加载数据失败,JVM直接退出,避免后续启动不可用;

2-「付钱拉」的实时类交易处理响应时间最长是40s,如果超过40s前置系统就不再等待,释放线程,告知商户正在处理中,后续有处理结果会以通知的方式或者业务线主动查询的方式得到结果;

3-「付钱拉」使用了redis做缓存数据库,用到的地方有实时报警埋点和验重等功能。如果连接redis超过50ms,那么这笔redis操作会自动放弃,在最坏的情况下这个操作带给支付的影响也就是50ms,控制在系统允许的范围内。

设计具备自我保护能力的系统

系统一般都有第三方依赖,比如数据库,三方接口等。系统开发的时候,需要对第三方保持怀疑,避免第三方出现问题时候的连锁反应,导致宕机。

(1)拆分消息队列

「付钱拉」提供各种各样的支付接口给商户,常用的就有快捷,个人网银,企业网银,退款,撤销,批量代付,批量代扣,单笔代付,单笔代扣,语音支付,余额查询,身份证鉴权,银行卡鉴权,卡密鉴权等。与其对应的支付通道有微信支付,ApplePay,支付宝等30多家支付通道,并且接入了几百家商户。在这三个维度下,如何确保不同业务、三方、商户、以及支付类型互不影响,「付钱拉」所做的就是拆分消息队列。下图是部分业务消息队列拆分图:



(2)限制资源的使用

对于资源使用的限制设计是高可用系统最重要的一点,也是容易被忽略的一点,资源相对有限,用的过多了,自然会导致应用宕机。为此「付钱拉」做了以下功课:

限制连接数

随着分布式的横向扩展,需要考虑数据库连接数,而不是无休止的最大化。数据库的连接数是有限制的,需要全局考量所有的模块,特别是横向扩展带来的增加。

限制内存的使用

内存使用过大,会导致频繁的GC和OOM,内存的使用主要来自以下两个方面:

1.集合容量过大;

2.未释放已经不再引用的对象,比如放入ThreadLocal的对象一直会等到线程退出的时候回收。

限制线程创建

线程的无限制创建,最终导致其不可控,特别是隐藏在代码中的创建线程方法。

当系统的SY值过高时,表示linux需要花费更多的时间进行线程切换。Java造成这种现象的主要原因是创建的线程比较多,且这些线程都处于不断的阻塞(锁等待,IO等待)和执行状态的变化过程中,这就产生了大量的上下文切换。

除此之外,Java应用在创建线程时会操作JVM堆外的物理内存,太多的线程也会使用过多的物理内存。对于线程的创建,最好通过线程池来实现,避免线程过多产生上下文切换。

限制并发

做过支付系统的应该清楚,部分三方支付公司是对商户的并发有要求的。三方给开放几个并发是根据实际交易量来评估的,所以如果不控制并发,所有的交易都发给三方,那么三方只会回复“请降低提交频率”。

所以在系统设计阶段和代码review阶段都需要特别注意,将并发限制在三方允许的范围内。

上篇完

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 我曾经想过与你在一起的那个家。我想了很久窗帘的颜色,想过每天清晨睁眼见到你的欢喜。我想过厨房的格局,想过我做饭的时...
    若水南珂阅读 320评论 4 4
  • 远在北京的亲家亲家母喜得千金,母女平安,可喜可贺! 我们都是SFYZ 208班的同窗,自己也算是亲眼见证了他俩的“...
    都市打工人阅读 205评论 0 1
  • 从儿童心理学角度来说,孩子“执拗”这个问题其实并不难解,首先咱们得先多站在孩子的角度看问题,他们是不是饿了,困了,...
    不吃面条always阅读 373评论 0 0