支付新手高頻易發故障及應對
在支付行業的技術領域,新手開發者常常會遇到各種技術挑戰和故障。本文匯總了支付新手高頻易發的故障,并提供了實用的應對策略,供大家參考。
一路走來,我犯過很多錯,也引發過很多線上故障。在帶團隊后,也不斷看到團隊內的新人頻繁出現各種線上故障。這些故障或多或少都對公司的業務和新人的心理造成了一定的負面影響。
這里匯總一些新手高頻易發的故障,以及應對策略,少點故障,安心過年。主要包括:渠道返回碼,亂序,三高(高并發、高性能、高可用),冪等,多幣種等。
1. 對外部渠道的返回碼理解一知半解
無論是四方還是三方,大部分情況下都是調用外部渠道或銀行做真實的扣款,而渠道對接是新手觸發故障的高風險區。
首先就是渠道返回碼的映射。最常見的就是把渠道返回“系統異?!?、“訂單不存在”、或調用超時,推進到失敗。
我現在還記得我接入的第一個外部渠道,吭哧吭哧前后忙活了1個多月,終于上線,開量,穩定運行,非常開心。
有天財務小妹找到我,說我接的那個渠道有筆支付訂單對賬出了長款,我們的訂單是失敗的,但是渠道給的對賬文件是成功的。我不敢大意,趕緊去查日志和數據庫的數據,原來是渠道支付接口超時,查詢接口返回“訂單不存在”,被映射到了“失敗”。
當時被老板被狠批一頓:“你怎么犯這種低級錯誤!怎么能把訂單不存在映射成失敗呢?”那時年輕,毫不客氣地回敬道:“這是銀行的問題哪,他都告訴我訂單不存在了,我咋還不能推進到失敗呢?我不推進到失敗我推進到哪里?”
雖然嘴硬,心還是虛的。在網絡環境下,數據包走不同的路由分發,銀行內部多個系統之間有延時,最后導致查詢比支付先到,或者查詢時數據還沒有落庫,銀行返回訂單不存在,很正常的。
梳理出大致如下幾條準則:
- 只有明確成功,才能推進成功。
- 只有明確失敗,才能推進失敗。
- 結果不明確,默認全部是“未知”。
- 支付場景謹慎推進到成功,退款、提現、商家打款等場景謹慎推進到失敗。
- 典型的結果不明確場景有:訂單不存在,系統異常,內部錯誤等。
這部分在“渠道返回碼映射設計與最佳實踐”的那篇文章里寫得更清楚明確,有興趣的可以歷史發文里面找一找。
2. 缺少亂序的概念
人的大腦是順序思維,但互聯網世界是亂序的。
比如以前發生一個線上問題,財務小妹說和建行的對賬對出了長款:銀行支付成功,我方不是成功。一查,原來是渠道異步通知接口先返回了“成功”,單據先被推進到了成功,然后同步接口才返回“系統異常”,單據又被推進到了支付失敗。
這里有兩個問題:
1)不應該把系統異常映射到失敗,這個在上面的返回碼映射已經說得非常清楚。
2)成功是終態,不應該再變更。
第2個問題的解法非常簡單,只需要設計好狀態機就行。比如終態不可變,只有符合要求的初始狀態+指定事件,才能推進到指定的狀態。有興趣的,可去找公號歷史發文里面的“支付交易訂單狀態機設計與最佳實踐”,寫得非常詳細。
不僅僅是外部渠道對接,現在互聯網應用都是微服務架構,微服務之間除了api接口,還通過消息來傳遞數據,而大部分消息是不保證順序性的。
我時不時聽見一些新人質問消息發送方:“為什么你的數據沒有順序,你需要保證你的數據要有順序,不然我處理不了!”。我只能啞然一笑。
群里也有小伙伴說某某消息中間件可以保證有序性??墒俏覀內绻O計一個系統,不依賴中間件來保證順序性,不是更好么?極端場景下,就算消息中間件能保證順序性,但在分布式場景下,我們也無法保證一筆業務只在一臺服務器上處理。
3. 缺少三高的概念
“高并發、高可用、高性能”雖然很虛,卻又很實在。不同數量級的并發,對系統的要求是截然不同的?!皦核礼橊劦淖詈笠桓静荨痹诖笠幠=灰讏鼍跋?,不是一句笑話,而是真實存在的。
以前很長一段時間我分辨不出“高并發”和“高性能”之間區別,以為兩者是一回事。事實不是,高并發是指同時能接多少請求,比如同時處理1百個請求,還是1萬個請求,就是并發的概念。高性能是指一個請求需要處理多少時間,比如平均每個請求處理時間是500毫秒,性能就遠好于平均處理時間1000毫秒。
舉幾個例子:
高性能:用戶一般可以使用多個支付方式,比如余額、紅包、滿減、外部銀行等,分別保存在不同的子應用中,沒有經驗的新人,就按順序去各個應用中查數據。有經驗的老人就知道,使用多線程同時去各子應用中查數據。這就是提高性能的方式。
高可用:以前分享過一個故障,后臺操作出現慢查詢,在線業務去緩存查數據,擊穿到數據庫,數據庫宕機,進而導致線上業務宕機。最后分析下來,在線業務對那個緩存數據是弱依賴,沒有也能部分有損地處理業務。這就是高可用的部分。有興趣的可以看看公號里的歷史發文中的一些故障分享。
高并發:高并發引發的問題太多了。比如代碼new 一個大對象,小流量沒事,流量一大,就會出現頻繁full gc。比如數據庫連接沒有按預期釋放,小流量也沒事,流量一大,連接不夠用,就會出現頻繁報錯。
這三塊在網上有很多資料,邊看邊學邊實踐,沒什么好辦法。
4. 缺少冪等概念
在支付系統中,冪等極其重要,一旦出現冪等失敗,經常導致資損,不是平臺資損,就是用戶資損。
常見有三種:
對外提供的接口升級,導致冪等失效。現在互聯網應用對外的接口都會聲明冪等字段,最怕就是內部做升級,不小心把冪等組合修改掉,比如原來使用訂單號,后面使用訂單號+日期,上游訂單號沒有變,日期變了,本應該是一筆訂單,因為冪等失敗,就成了兩筆訂單。
調用下游接口,把下游依賴的冪等字段內容修改了。比如下游依賴訂單號+創建日期做冪等,上游在架構升級中,傳入了訂單號+當前日期,在跨零點的交易中,就可能出現冪等失敗。
使用redis實現的分布式鎖做冪等。redis的可靠性和持久存儲是比不上關系數據庫的,最起碼需要使用關系數據庫的唯一索引做冪等。
冪等在網上有很多資料,值得好好看看。更高階的,還需要考慮異地多活的冪等場景,A機房掛了,去到B機房,會不會冪等失敗。
5. 缺少多幣種或金額單位換算概念
在跨境交易中,必然是多幣種的,不同的幣種,最小單位是不一樣的。人民幣、美元都很標準,有元有分,但是日元最小單位就是元,印尼盾雖然最小單位是分,但是日常只會用到元。
在微服務框架中,如果一些子應用中使用分,一些子應用使用元,會出現什么情況?
新人還容易犯的一個錯誤就是手動加減乘除,容易出現金額放大縮小100倍,或者出現舍入不正確(舍入有:向下取整,向上取整,四舍五入、銀行家算法等)。尤其是渠道對接時,以為內部使用的分,外部渠道接口要求是元,直接乘100,但實際上內部應用使用的是元,妥妥資損100倍。
解決方案在公號以前的發文“支付系統金額處理規范及最佳實踐”中有詳細說明,有興趣可以去翻翻。
6. 結束語
上面只是舉了一些常見的例子,無法覆蓋全部。
基本所有的新人都是踩著線上故障在成長。我們能做的,只是提供一些規范或案例,讓新人能踩在前人的故障上成長,而不全是踩著自己的線上故障在成長。很多時候一不小心因為一個大故障而被清理門戶,成長雖有,代價卻過大,得不償失。
本文由人人都是產品經理作者【隱墨星辰】,微信公眾號:【隱墨星辰】,原創/授權 發布于人人都是產品經理,未經許可,禁止轉載。
題圖來自Unsplash,基于 CC0 協議。
- 目前還沒評論,等你發揮!