ZERO TO ONE |「付錢拉」支付系統(tǒng)架構(gòu)系列二:如何提高應(yīng)用的可用性(上篇)

對(duì)于互聯(lián)網(wǎng)應(yīng)用和企業(yè)大型應(yīng)用而言,多數(shù)都盡可能地要求做到7*24小時(shí)不間斷運(yùn)行绿鸣,而要做到完全的不間斷運(yùn)行可以說(shuō)“難于上青天”。

為此,對(duì)應(yīng)用的可用性程度一般衡量標(biāo)準(zhǔn)有三個(gè)9到五個(gè)9砸逊。



對(duì)于一個(gè)功能和數(shù)據(jù)量不斷增加的應(yīng)用,要保持比較高的可用性并非易事掌逛。為了實(shí)現(xiàn)高可用师逸,「付錢拉」?從避免單點(diǎn)故障、保證應(yīng)用自身的高可用豆混、解決交易量增長(zhǎng)等方面做了許多探索和實(shí)踐篓像。

在不考慮外部依賴系統(tǒng)突發(fā)故障,如網(wǎng)絡(luò)問(wèn)題皿伺、三方支付和銀行的大面積不可用等情況下员辩,「付錢拉」的服務(wù)能力可以達(dá)到99.999%。

本文重點(diǎn)討論如何提高應(yīng)用自身的可用性鸵鸥,關(guān)于如何避免單點(diǎn)故障和解決交易量增長(zhǎng)問(wèn)題會(huì)在其他系列討論奠滑。

為了提高應(yīng)用的可用性,首先要做的就是盡可能避免應(yīng)用出現(xiàn)故障,但要完全做到不出故障是不可能的养叛≈帜牛互聯(lián)網(wǎng)是個(gè)容易產(chǎn)生“蝴蝶效應(yīng)”的地方,任何一個(gè)看似很小的弃甥、發(fā)生概率為0的事故都可能出現(xiàn)爽室,然后被無(wú)限放大。

大家都知道RabbitMQ本身是非常穩(wěn)定可靠的淆攻,「付錢拉」最開(kāi)始也一直在使用單點(diǎn)RabbitMQ阔墩,并且從未出現(xiàn)運(yùn)行故障,所以大家在心理上都認(rèn)為這個(gè)東西不太可能出問(wèn)題瓶珊。

直到某天啸箫,這臺(tái)節(jié)點(diǎn)所在的物理主機(jī)硬件因?yàn)槟昃檬迚牡袅耍?dāng)時(shí)這臺(tái)RabbitMQ就無(wú)法提供服務(wù)伞芹,導(dǎo)致系統(tǒng)服務(wù)瞬間不可用忘苛。

故障發(fā)生了也不可怕,最重要的是及時(shí)發(fā)現(xiàn)并解決故障唱较。「付錢拉」對(duì)自身系統(tǒng)的要求是扎唾,秒級(jí)發(fā)現(xiàn)故障,快速診斷和解決故障南缓,從而降低故障帶來(lái)的負(fù)面影響胸遇。

首先我們簡(jiǎn)單的回顧一下,「付錢拉」曾經(jīng)碰到的一些問(wèn)題:

以史為鑒

1

新來(lái)的開(kāi)發(fā)同事在處理新接入的三方通道時(shí)汉形,由于經(jīng)驗(yàn)不足忽視了設(shè)置超時(shí)時(shí)間的重要性纸镊。就是這樣一個(gè)小小的細(xì)節(jié),導(dǎo)致這個(gè)三方隊(duì)列所在的交易全部堵塞概疆,同時(shí)影響到其他通道的交易逗威。

2

「付錢拉」系統(tǒng)是分布式部署的,并且支持灰度發(fā)布届案,所以環(huán)境和部署模塊非常多而且復(fù)雜庵楷。某次增加了一個(gè)新模塊,由于存在多個(gè)環(huán)境楣颠,且每個(gè)環(huán)境都是雙節(jié)點(diǎn)尽纽,新模塊上線后導(dǎo)致數(shù)據(jù)庫(kù)的連接數(shù)不夠用,從而影響其他模塊功能童漩。

3

同樣是超時(shí)問(wèn)題弄贿,一個(gè)三方的超時(shí),導(dǎo)致耗盡了當(dāng)前所配置的所有worker threads, 以至于其他交易沒(méi)有可處理的線程矫膨。

4

A三方同時(shí)提供鑒權(quán)差凹,支付等接口期奔,其中一個(gè)接口因?yàn)?b>「付錢拉」交易量突增,從而觸發(fā)A三方在網(wǎng)絡(luò)運(yùn)營(yíng)商那邊的DDoS限制危尿。通常機(jī)房的出口IP都是固定的呐萌,從而被網(wǎng)絡(luò)運(yùn)營(yíng)商誤認(rèn)為是來(lái)自這個(gè)出口IP的交易是流量攻擊,最終導(dǎo)致A三方鑒權(quán)和支付接口同時(shí)不可用谊娇。

5

再說(shuō)一個(gè)數(shù)據(jù)庫(kù)的問(wèn)題肺孤,同樣是因?yàn)?b>「付錢拉」交易量突增引發(fā)的。建立序列的同事給某個(gè)序列的上限是999济欢,999赠堵,999,但數(shù)據(jù)庫(kù)存的這個(gè)字段長(zhǎng)度是32位法褥,當(dāng)交易量小的時(shí)候茫叭,系統(tǒng)產(chǎn)生的值和字段32位是匹配的,序列不會(huì)升位半等∽岢睿可是隨著交易量的增加,序列不知不覺(jué)的升位數(shù)了杀饵,結(jié)果導(dǎo)致32位就不夠存放吗垮。類似這樣的問(wèn)題對(duì)于互聯(lián)網(wǎng)系統(tǒng)非常常見(jiàn),并且具有隱蔽性凹髓,所以如何避免就顯得非常重要了。

◆◆◆◆

下面我們從三個(gè)方面來(lái)看「付錢拉」所做的改變怯屉。

(一)盡可能避免故障

設(shè)計(jì)可容錯(cuò)的系統(tǒng)

比如重路由蔚舀,對(duì)于用戶支付來(lái)說(shuō),用戶并不關(guān)心自己的錢具體是從哪個(gè)通道支付出去的锨络,用戶只關(guān)心成功與否赌躺。「付錢拉」連接30多個(gè)通道,有可能A通道支付不成功羡儿,這個(gè)時(shí)候就需要?jiǎng)討B(tài)重路由到B或者C通道礼患,這樣就可以通過(guò)系統(tǒng)重路由避免用戶支付失敗,實(shí)現(xiàn)支付容錯(cuò)掠归。


還有針對(duì)OOM做容錯(cuò)缅叠,像Tomcat一樣。系統(tǒng)內(nèi)存總有發(fā)生用盡的情況虏冻,如果一開(kāi)始就對(duì)應(yīng)用本身預(yù)留一些內(nèi)存肤粱,當(dāng)系統(tǒng)發(fā)生OOM的時(shí)候,就可以catch住這個(gè)異常厨相,從而避免這次OOM领曼。

某些環(huán)節(jié)快速失敗“fail fast原則”

Fail fast原則是當(dāng)主流程的任何一步出現(xiàn)問(wèn)題的時(shí)候鸥鹉,應(yīng)該快速合理地結(jié)束整個(gè)流程,而不是等到出現(xiàn)負(fù)面影響才處理庶骄。

舉個(gè)幾個(gè)例子:

1-「付錢拉」啟動(dòng)的時(shí)候需要加載一些隊(duì)列信息和配置信息到緩存毁渗,如果加載失敗或者隊(duì)列配置不正確,會(huì)造成請(qǐng)求處理過(guò)程的失敗单刁,對(duì)此最佳的處理方式是加載數(shù)據(jù)失敗灸异,JVM直接退出,避免后續(xù)啟動(dòng)不可用幻碱;

2-「付錢拉」的實(shí)時(shí)類交易處理響應(yīng)時(shí)間最長(zhǎng)是40s绎狭,如果超過(guò)40s前置系統(tǒng)就不再等待,釋放線程褥傍,告知商戶正在處理中儡嘶,后續(xù)有處理結(jié)果會(huì)以通知的方式或者業(yè)務(wù)線主動(dòng)查詢的方式得到結(jié)果;

3-「付錢拉」使用了redis做緩存數(shù)據(jù)庫(kù)恍风,用到的地方有實(shí)時(shí)報(bào)警埋點(diǎn)和驗(yàn)重等功能蹦狂。如果連接redis超過(guò)50ms,那么這筆redis操作會(huì)自動(dòng)放棄朋贬,在最壞的情況下這個(gè)操作帶給支付的影響也就是50ms凯楔,控制在系統(tǒng)允許的范圍內(nèi)。

設(shè)計(jì)具備自我保護(hù)能力的系統(tǒng)

系統(tǒng)一般都有第三方依賴锦募,比如數(shù)據(jù)庫(kù)摆屯,三方接口等。系統(tǒng)開(kāi)發(fā)的時(shí)候糠亩,需要對(duì)第三方保持懷疑虐骑,避免第三方出現(xiàn)問(wèn)題時(shí)候的連鎖反應(yīng),導(dǎo)致宕機(jī)赎线。

(1)拆分消息隊(duì)列

「付錢拉」提供各種各樣的支付接口給商戶廷没,常用的就有快捷,個(gè)人網(wǎng)銀垂寥,企業(yè)網(wǎng)銀颠黎,退款,撤銷滞项,批量代付狭归,批量代扣,單筆代付文判,單筆代扣唉铜,語(yǔ)音支付,余額查詢律杠,身份證鑒權(quán)潭流,銀行卡鑒權(quán)竞惋,卡密鑒權(quán)等。與其對(duì)應(yīng)的支付通道有微信支付灰嫉,ApplePay拆宛,支付寶等30多家支付通道,并且接入了幾百家商戶讼撒。在這三個(gè)維度下浑厚,如何確保不同業(yè)務(wù)、三方根盒、商戶钳幅、以及支付類型互不影響,「付錢拉」所做的就是拆分消息隊(duì)列炎滞。下圖是部分業(yè)務(wù)消息隊(duì)列拆分圖:



(2)限制資源的使用

對(duì)于資源使用的限制設(shè)計(jì)是高可用系統(tǒng)最重要的一點(diǎn)敢艰,也是容易被忽略的一點(diǎn),資源相對(duì)有限册赛,用的過(guò)多了钠导,自然會(huì)導(dǎo)致應(yīng)用宕機(jī)。為此「付錢拉」做了以下功課:

限制連接數(shù)

隨著分布式的橫向擴(kuò)展森瘪,需要考慮數(shù)據(jù)庫(kù)連接數(shù)牡属,而不是無(wú)休止的最大化。數(shù)據(jù)庫(kù)的連接數(shù)是有限制的扼睬,需要全局考量所有的模塊逮栅,特別是橫向擴(kuò)展帶來(lái)的增加。

限制內(nèi)存的使用

內(nèi)存使用過(guò)大窗宇,會(huì)導(dǎo)致頻繁的GC和OOM证芭,內(nèi)存的使用主要來(lái)自以下兩個(gè)方面:

1.集合容量過(guò)大;

2.未釋放已經(jīng)不再引用的對(duì)象担映,比如放入ThreadLocal的對(duì)象一直會(huì)等到線程退出的時(shí)候回收。

限制線程創(chuàng)建

線程的無(wú)限制創(chuàng)建叫潦,最終導(dǎo)致其不可控蝇完,特別是隱藏在代碼中的創(chuàng)建線程方法。

當(dāng)系統(tǒng)的SY值過(guò)高時(shí)矗蕊,表示linux需要花費(fèi)更多的時(shí)間進(jìn)行線程切換短蜕。Java造成這種現(xiàn)象的主要原因是創(chuàng)建的線程比較多,且這些線程都處于不斷的阻塞(鎖等待傻咖,IO等待)和執(zhí)行狀態(tài)的變化過(guò)程中朋魔,這就產(chǎn)生了大量的上下文切換。

除此之外卿操,Java應(yīng)用在創(chuàng)建線程時(shí)會(huì)操作JVM堆外的物理內(nèi)存警检,太多的線程也會(huì)使用過(guò)多的物理內(nèi)存孙援。對(duì)于線程的創(chuàng)建,最好通過(guò)線程池來(lái)實(shí)現(xiàn)扇雕,避免線程過(guò)多產(chǎn)生上下文切換拓售。

限制并發(fā)

做過(guò)支付系統(tǒng)的應(yīng)該清楚,部分三方支付公司是對(duì)商戶的并發(fā)有要求的镶奉。三方給開(kāi)放幾個(gè)并發(fā)是根據(jù)實(shí)際交易量來(lái)評(píng)估的础淤,所以如果不控制并發(fā),所有的交易都發(fā)給三方哨苛,那么三方只會(huì)回復(fù)“請(qǐng)降低提交頻率”鸽凶。

所以在系統(tǒng)設(shè)計(jì)階段和代碼review階段都需要特別注意,將并發(fā)限制在三方允許的范圍內(nèi)建峭。

上篇完

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末玻侥,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子迹缀,更是在濱河造成了極大的恐慌使碾,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祝懂,死亡現(xiàn)場(chǎng)離奇詭異票摇,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)砚蓬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門矢门,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人灰蛙,你說(shuō)我怎么就攤上這事祟剔。” “怎么了摩梧?”我有些...
    開(kāi)封第一講書人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵物延,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我仅父,道長(zhǎng)叛薯,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任笙纤,我火速辦了婚禮耗溜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘省容。我一直安慰自己抖拴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布腥椒。 她就那樣靜靜地躺著阿宅,像睡著了一般候衍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上家夺,一...
    開(kāi)封第一講書人閱讀 49,842評(píng)論 1 290
  • 那天脱柱,我揣著相機(jī)與錄音,去河邊找鬼拉馋。 笑死榨为,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的煌茴。 我是一名探鬼主播随闺,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蔓腐!你這毒婦竟也來(lái)了矩乐?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤回论,失蹤者是張志新(化名)和其女友劉穎散罕,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體傀蓉,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡欧漱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了葬燎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片误甚。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖谱净,靈堂內(nèi)的尸體忽然破棺而出窑邦,到底是詐尸還是另有隱情,我是刑警寧澤壕探,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布冈钦,位于F島的核電站,受9級(jí)特大地震影響李请,放射性物質(zhì)發(fā)生泄漏瞧筛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一捻艳、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧庆猫,春花似錦认轨、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)恩急。三九已至,卻和暖如春纪蜒,著一層夾襖步出監(jiān)牢的瞬間衷恭,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工纯续, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留随珠,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓猬错,卻偏偏與公主長(zhǎng)得像窗看,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子倦炒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,796評(píng)論 25 707
  • 我曾經(jīng)想過(guò)與你在一起的那個(gè)家显沈。我想了很久窗簾的顏色,想過(guò)每天清晨睜眼見(jiàn)到你的歡喜逢唤。我想過(guò)廚房的格局拉讯,想過(guò)我做飯的時(shí)...
    若水南珂閱讀 330評(píng)論 4 4
  • 遠(yuǎn)在北京的親家親家母喜得千金,母女平安鳖藕,可喜可賀魔慷! 我們都是SFYZ 208班的同窗,自己也算是親眼見(jiàn)證了他倆的“...
    浮生夢(mèng)一場(chǎng)閱讀 222評(píng)論 0 1
  • 從兒童心理學(xué)角度來(lái)說(shuō)吊奢,孩子“執(zhí)拗”這個(gè)問(wèn)題其實(shí)并不難解盖彭,首先咱們得先多站在孩子的角度看問(wèn)題,他們是不是餓了页滚,困了召边,...
    不吃面條always閱讀 389評(píng)論 0 0