轉(zhuǎn)轉(zhuǎn)支付通道監(jiān)控系統(tǒng)的搭建
1 背景介紹
為了滿足不斷增長的業(yè)務(wù)需求,轉(zhuǎn)轉(zhuǎn)逐步接入了大量的支付通道,而第三方系統(tǒng)的穩(wěn)定性參差不齊,通道故障時有發(fā)生。當三方通道發(fā)生異常時我們的感知比較后置,比如大量的系統(tǒng)告警,甚至需要等業(yè)務(wù)或用戶反饋才能感知到異常。作為承接全公司支付業(yè)務(wù)的核心系統(tǒng),想要建立一個能給上游提供穩(wěn)定服務(wù)的系統(tǒng),僅依靠人工維護是遠遠不夠的,因此建立一個完善的支付通道自動化管理系統(tǒng)就提上了日程。
2 設(shè)計目標
結(jié)合轉(zhuǎn)轉(zhuǎn)自身業(yè)務(wù)的特點,我們整理了支付通道自動化管理系統(tǒng)重點需要解決的問題:
- 多通道、多主體的通道監(jiān)控能力;
- 故障快速發(fā)現(xiàn),快速定位異常原因;
- 盡量做到無誤報、無漏報;
- 通道故障自動化切換的能力;
3 技術(shù)選型
基于以上背景,再來看下技術(shù)方案的選型:
3.1 熔斷器
提到故障的熔斷和降級,首先想到的是市面上成熟的組件是否能夠滿足,比如 Hystrix,結(jié)合轉(zhuǎn)轉(zhuǎn)當前的業(yè)務(wù)場景來看,有以下幾點無法滿足訴求:
- 熔斷器的降級熔斷是基于接口的,無法滿足通道和商戶號維度的降級;
- 流量回切時可能異常仍未恢復,無法自定義探測流量的范圍,比如回切時指定用戶或業(yè)務(wù),容易造成二次事故;
3.2 時序數(shù)據(jù)庫
熔斷器無法滿足目標后,我們就將目標轉(zhuǎn)向了自研,首先想做一個監(jiān)控系統(tǒng),底層一般都是選用時序數(shù)據(jù)庫來存儲,以下是熱門時序數(shù)據(jù)庫的排名:
時序數(shù)據(jù)庫排名
結(jié)合轉(zhuǎn)轉(zhuǎn)目前的現(xiàn)狀,我們最終將范圍鎖定在了 Prometheus 和基于 Redis 自研:
準確性方面: 由于 Prometheus 在設(shè)計上就放棄了一部分數(shù)據(jù)準確性,放棄一點準確性得到的是更高的可靠性,架構(gòu)簡單、數(shù)據(jù)簡單、運維簡單、節(jié)約機器成本與人力成本。
通常對于監(jiān)控系統(tǒng),數(shù)據(jù)擁有少量的誤差是可以接受的,而對于自動切換通道這種高敏感場景并不適用:
- 比如在兩次采樣的間隔 (15s) 中有一個瞬時小尖峰,那么這次小尖峰是觀察不到的
- 再比如 QPS、RT、P95、P99 這些值都是估算值,無法和日志、數(shù)據(jù)庫一樣做到 100% 準確
Prometheus 不適合的場景
接入和學習成本方面: Prometheus 對于業(yè)務(wù)研發(fā)來講還是有一定的學習成本的,也不便于后期的維護,而 Redis 對于 Java 后端開發(fā)者來說再熟悉不過了,無論是前期的學習成本還是后期的維護成本都比較低。
結(jié)合以上幾個方面考量,最終決定基于 Redis 自研 “時序數(shù)據(jù)庫” 來滿足當前的訴求。
4 架構(gòu)設(shè)計
架構(gòu)設(shè)計
收款和付款時會先通過各自的通道路由,篩選出可用的支付通道列表,獲取到通道之后調(diào)用網(wǎng)關(guān)下單或打款,再由網(wǎng)關(guān)來向三方發(fā)起請求,請求結(jié)束后將三方返回的結(jié)果通過 MQ 上報到通道監(jiān)控系統(tǒng)。
監(jiān)控系統(tǒng)在監(jiān)聽到消息后,將監(jiān)控的數(shù)據(jù)存儲到 Redis,再由數(shù)據(jù)計算模塊拉取 Redis 的數(shù)據(jù)進行篩選過濾后,匯總計算各通道的失敗率,最后根據(jù)各通道配置的告警規(guī)則觸發(fā)通道異常告警。
Redis 中的數(shù)據(jù)會定期向 MySQL 備份,以便后續(xù)故障分析使用,同時會有離線任務(wù)定時清理 Redis 中的數(shù)據(jù),避免 Redis 中存儲的數(shù)據(jù)量過大。
同時為了更直觀的觀察各通道數(shù)據(jù)指標的變化,將收集到的數(shù)據(jù)指標上報到了 Prometheus,通過 Grafana 數(shù)據(jù)看板來觀察通道健康度。
通道指標看板
通道自動上下線是比較敏感的操作,嚴格依賴算法的準確性,所以系統(tǒng)上線初期,我們只上線了手動上下線的能力,需要在收集大量樣本后,不斷完善算法,提高監(jiān)控的準確性和靈敏度,再逐步切換至基于監(jiān)控的通道自動化管理。
5 實現(xiàn)細節(jié)
5.1 數(shù)據(jù)結(jié)構(gòu)
再來看下基于 Redis 的數(shù)據(jù)存儲是如何存儲的,雖然沒有使用時序數(shù)據(jù)庫,但是在數(shù)據(jù)結(jié)構(gòu)選擇上也是結(jié)合了時序數(shù)據(jù)庫的存儲思想來設(shè)計的,下面就以最熱門的 InfluxDB 來對比看下:
InfluxDB | Redis |
tags 標簽 | set 記錄監(jiān)控維度 |
time 時間戳 | zset 存儲時間戳(秒) |
fields 數(shù)據(jù) | hash 存儲具體的值 |
- tags 標簽:記錄監(jiān)控的維度,相對應(yīng)的在 Redis 中選用的是 set 來存儲,利用 set 去重的特性,剛好可以記錄需要監(jiān)控的指標。
- tims 時間:記錄發(fā)生的時間,相對應(yīng)的在 Redis 中選用的是 zset 來存儲,在監(jiān)控時需要根據(jù)時間范圍進行查找,且要求是按照時間排序的,剛好可以利用 zset 的按照 score 來排序和查找的特性,用于記錄監(jiān)控點位的時間戳,為了避免數(shù)據(jù)量過大,這里記錄的單位是秒,也就一秒一個點位。
- fields 數(shù)據(jù):存儲具體的監(jiān)控數(shù)據(jù),相對應(yīng)的在 Redis 中選用的是 hash 來存儲,利用 hash 中存儲 key、value 的特性,來記錄請求結(jié)果數(shù)據(jù),記錄一個點位內(nèi)(1 秒)的成功與失敗的情況,并記錄失敗的具體原因,key 用來存儲請求結(jié)果,value 用來記錄對應(yīng)結(jié)果 1 秒內(nèi)發(fā)生的次數(shù)。
最終 Redis 中存儲的結(jié)構(gòu)樣例如下:
1.set
存儲已統(tǒng)計的維度,具體到商戶號
key: routeAlarm:alarmitems
value: 微信-打款-100000111
微信-打款-100000112
微信-打款-100000113
.......
2.zset
存儲指定商戶號請求的時間戳(秒),同一秒的數(shù)據(jù)會覆蓋存儲
key: routeAlarm:alarmitem:timeStore:微信-打款-100000111
score: 1657164225 value: 1657164225
score: 1657164226 value: 1657164226
score: 1657164227 value: 1657164227
.......
3.hash
存儲指定商戶號1秒內(nèi)的請求結(jié)果, 每秒?yún)R總一份結(jié)果
key: routeAlarm:alarmitem:fieldStore:微信-打款-100000111:1657164225
key: success value: 10 (次數(shù))
key: fail value: 5
key: balance_not_enough value: 3
key: thrid_error value: 2
.......
5.2 核心算法
為了避免兩次監(jiān)控間的小高峰被忽略,確保不漏報,我們的算法采用的是局部 計數(shù)法 加上整體 滑動窗口 的方式來實現(xiàn)的,每秒一個計數(shù)的點位,記錄成功和失敗的數(shù)量,監(jiān)控時會計算整個窗口時間范圍內(nèi)的成功失敗數(shù),最終得出每個通道的失敗率,比如:窗口時間是1分鐘,監(jiān)控頻率 10秒/次。
核心算法
那么監(jiān)控頻率是多少、時間窗口范圍如何設(shè)定,這都會影響我們最終監(jiān)控的準確性。如果監(jiān)控頻率過小,就會導致我們的取數(shù)樣本太少,結(jié)果也沒有參考意義。如果監(jiān)控頻率過大,兩次窗口之間的小高峰就可能存在漏報的情況,這些都是影響告警準確性的因素,這就需要通過對各個通道單據(jù)量級如:每天、每小時單量、下單頻率等指標進行分析而確定。
5.3 小流量的處理
小流量的通道和時間段要如何處理
- 從通道維度看,小流量的通道如何處理
- 從時間維度看,底峰時間段如何處理
比如轉(zhuǎn)轉(zhuǎn)接入的某一通道,每天總量只有幾單,或者凌晨的單量就是很少,針對這種小流量的處理方式是,在監(jiān)控時間窗口內(nèi)只有 1 單且失敗,則會擴大時間窗口,比如我們正常時間窗口是 1 分鐘,那么擴大 1 倍后,時間窗口則變更為 2 分鐘,1-10 倍逐級增加,擴大到 10 倍之后如果還是高于預警閥值則會觸發(fā)告警,此時我們認為這種也是需要關(guān)注的異常。
6 最終效果
- 通道異常告警,快速定位問題
通道異常告警
- 合并重復告警項
合并重復告警項
- 通道異?;謴?/li>
通道異常恢復
7 未來規(guī)劃
目前的支付通道自動化管理系統(tǒng)還需要在以下幾個方面進行優(yōu)化和升級:
- 持續(xù)優(yōu)化監(jiān)控算法,提升告警準確率到99%以上;
- 與監(jiān)控系統(tǒng)配合,實現(xiàn)通道故障時自動下線的能力;
- 與監(jiān)控系統(tǒng)配合,實現(xiàn)故障恢復探測及通道自動上線的能力;
關(guān)于作者:張丹,轉(zhuǎn)轉(zhuǎn)支付結(jié)算技術(shù)部研發(fā)工程師,主要負責清結(jié)算方向的研發(fā)工作