415
京東網上商城
從架構到監控報警,支付係統的設計如何步步為營
企業所處發展階段不同,對支付係統的定位和架構也不盡相同。整體上來說,我們可以把一個公司的支付係統發展分為三個階段:
-
支付係統:支付作為一個(封閉)的、獨立的應用係統,為各係統提供支付功能支持。一般來說,這個係統僅限於為公司內部的業務提供支付支持,並且和業務緊密耦合。
-
支付服務:支付作為一個開發的係統,為公司內外部係統、各種業務提供支付服務。支付服務本身應該是和具體的業務解耦合的。
-
支付平台:支付作為一個可擴展的平台, 公司內外部的用戶可以在此基礎上定製開發自己的服務。
這個劃分有點勉強。簡單說,支付係統是僅供內部使用的,支付服務是支持公司內外部來調用的,支付平台是可以在服務的基礎上定製各種場景支持的。
一、支付係統架構
1、支付業務流程
區分兩個概念:支付和交易。支付是交易的一部分。一個簡單的交易過程包括:客戶下訂單,客戶完成支付,商家接收訂單,商家出貨。這裏僅考慮下訂單的流程。從軟件工程的角度, 我們首先需要明確下幾個參與者。
-
電商係統,指提供在線購物服務的係統。用戶在這個係統中完成交易。
-
支付係統,可以是電商係統的一個模塊,或者是個獨立的係統。這是本文的主角,用來完成支付過程。
-
用戶,在電商係統中敗家的那位。如果使用銀行卡做交易,那也被稱為持卡人。
-
用戶使用銀行卡交易時,發行這個銀行卡的機構稱為發卡行,或者發卡機構。
-
商家也需要一張卡,就是大家在淘寶開網店的時候要登記的銀行卡,最終需要把用戶給的錢打到這張卡上。
-
和發卡機構相對應的,大家聽到最多的是收單機構。如支付寶,微信等第三方支付公司,介紹業務的時候總少不了互聯網收單的工作。它們把用戶訂單收起來,找發卡行要錢,就有了收單業務。
主演都有了,下麵就是如何演出支付這場大戲了。正常的流程應該是這樣:
1、用戶提交訂單到電商係統,電商係統對訂單進行檢驗,無問題則調起支付接口執行支付。注意這裏支付接口是在服務器端調起的。一般支付接口很少從客戶端直接調起。為了安全,支付接口一般要求用HTTPS來訪問,並對接口做簽名。關於支付接口的設計,我將另起博文介紹。
2、支付係統檢查參數有效性,特別是簽名的有效性。
3、根據用戶選擇的支付方式,以及係統支付路由設置,選擇合適的收單機構。這裏涉及三個概念,支付方式,支付路由。這又是一個槽點。簡單說,用戶可以選擇各種銀行卡支付,比如寧波銀行卡,但是你的支付係統沒有對接寧波銀行,那對這種卡,可以選擇你接入的,支持這個卡的收單機構來執行支付,如用微信或者支付寶等等第三方支付,或者銀聯支付等係統支持的方式來執行。這就是支付路由,根據用戶提供的銀行卡來選擇合適的收單機構去執行支付。常用支付方式還包括第三方支付,如微信支付寶等,這種情況下就不需要支付路由了。
4、調用收單接口執行支付。這是支付係統的核心。每個公司的收單接口都不一樣,接入一兩個收單機構還好,接入的多了,如何統一這些接口,就是一個設計難點。
5、支付成功,收單機構把錢打到商戶的賬戶上了。 商家就準備發貨了。 怎麼發貨,不是本文的重點。 這裏關注的要點是, 商家能收到多少錢? 比如100塊錢的商品,用戶支付了100塊錢(運費、打折等另算),這100塊錢,還要刨去電商係統的傭金、支付通道的手續費,才能最終落到商家手裏。
這是個Happy流程,一切看起來都很美好,但實際上步步都是坑,一旦有地方考慮不周全,輕者掉單頻發,重者接口被盜刷,損失慘重。
如何避免攻擊者修改支付接口參數, 比如100塊錢的東西,改成10塊錢?
調用收單接口來執行最終實際支付時,如果支付失敗了,比如卡上沒錢了,怎麼辦?
收單接口把賬戶上的錢扣走了,但是通知支付係統的時候出錯了(比如網絡閃斷,或者支付係統重啟了),支付係統不知道這筆交易已經達成了,怎麼處理?
還有好多問題……
和錢打交道,在任何公司,都跑不掉財務部門。 那財務部門會關注哪些內容? 當然,最重要的是賬務信息。 所有的交易都要記賬,按要求公司都需要定期做審計,每一筆帳都不能出錯。這當然不能等到審計的時候再去核對,而是每天都需要對賬,確保所有的交易支出相抵,也就是所說的把賬給平了。 這就有三種情況: 電商係統和商家對賬;電商係統和支付係統對賬;支付係統和收單機構對賬。作為支付係統,我們僅關注後兩者的情況。
從軟件開發角度, 還有一些非功能性需求需要實現:
-
性能: 特別是秒殺的時候,如何滿足高頻率的支付需求?
-
可靠性:不用說,係統能達到幾個9,是衡量軟件設計功力的重要指標。 99%是基礎, 99.999%是目標,更多的9那就是神了。
-
易用性:支付中多一個步驟,就會流失至少2%的用戶。 產品經理都在削尖腦袋想想怎麼讓用戶趕緊掏錢。
-
可擴展性: 近年來支付業務創新產品多,一元購、紅包、打賞等,還有各種的支付場景。 怎麼能夠快速滿足產品經理的需求,盡快上線來搶占市場,可擴展性對支付係統設計也是一個挑戰。
-
可伸縮性:為了支持公司業務,搞一些促銷活動是必須的。 那促銷帶來的爆發流量,最佳應對方法就是加機器了。 平時流量低,用不了那麼多機器,該釋放的就釋放掉了, 給公司省點錢。
2、支付的典型架構
所以支付的坑還不少,我們先看看互聯網的頭牌們是如何設計支付係統的? 先看看某團的:
再看某Q旅遊公司的:
對比下某東金融的:
最後看看業界最強的某金服金融的:
整體上來說, 從分層的角度,支付係統和普通的業務係統並沒有本質的區別,也是應用、服務、接口、引擎、存儲等分層。 在應用層,支付係統一般會提供如下子係統:
-
支付應用和產品(應用層): 這是針對各端(PC Web端、android、IOS)的應用和產品。 為各個業務係統提供收銀台支持,同時支付作為一個獨立的模塊,可以提供諸如銀行卡管理、理財、零錢、虛擬幣管理、交易記錄查閱、卡券等功能;
-
支付運營係統(應用層): 支付係統從安全的角度來說,有一個重要的要求是,懂代碼的不碰線上,管運營的不碰代碼。這對運營係統的要求就很高,要求基本上所有線上的問題,都可以通過運營係統來解決。
-
支付BI係統(應用層): 支付中產生大量的數據,對這些數據進行分析, 有助於公司老板們了解運營狀況,進行決策支持。
-
風控係統(應用層):這是合規要求的風險控製、反洗錢合規等。
-
信用信息管理係統(應用層):用來支持對信用算法做配置,對用戶的信用信息做管理。
其他各層功能:
-
支付服務層:為上述各端係統提供API。這些API也可以提供給業務係統直接使用。
-
接口層:和各相關係統對接的接口,其中最重要的是和支付渠道對接的支付網關。
-
引擎層: 包括統計分析、風控、反洗錢、信用評估等在後台運行的各個係統。
-
存儲層: 各種持久化的數據庫支持。
這其實也是普通互聯網應用係統架構,沒有什麼特別之處。比如微服務如何體現,如何滿足性能需求等,在這個視圖中無法體現出來。這隻是個軟件角度的高層視圖,後續我們對各個主要模塊進行分解,從分解視圖中可以知道如何滿足非功能性需求。
二、支付係統的監控與報警
關於監控,在各個技術網站,幾乎都是一搜一大把。幾個大的互聯網公司,也都有開發自己的監控係統。 關於這方麵也有不少分享。 這裏介紹針對支付係統的監控和報警,但大部分內容,應該來說,對其他係統也是通用的 。
現在基本上Zabbix成為監控的標配了。 一個常規的Zabbix監控實現, 是在被監控的機器上部署Zabbix Agent,從日誌中收集所需要的數據,分析出監控指標,發送到zabbix服務器上。!zabbix監控這種方式要求每個機器上部署Zabbix客戶端,並配置數據收集腳本。Zabbix的部署可以作為必裝軟件隨操作係統一起安裝。
1、係統監控
先說相對比較簡單的係統監控,一般係統監控關注如下指標:
-
CPU負載
-
內存使用率
-
磁盤使用率
-
網絡帶寬占用
這些指標在Zabbix agent中會提供默認實現,通過簡單配置即可激活。裝機時可以考慮統一配置這些監控。
2、JVM監控
JMX提供了關於JVM的大部分核心信息,啟動時設置參數,支持遠程訪問JMX,之後即可通過接入JMX來實時讀取JVM的CPU、內存等信息。Zabbix也支持通過JMX來獲取信息。
3、服務監控
服務監控主要指接口的狀態監控。 服務監控關注如下指標:
-
QPS:每秒請求數 對於使用容器的係統,包括Apache Tomcat,Resin,JBoss等,可以從Access Log中采集到每個接口的QPS。沒輸出Access Log的係統,考慮通過Annotation來規範輸出訪問計數。當然,這個指標還可以細分為 每秒成功請求數、失敗請求數、總請求數等。
-
請求響應時間:在服務器端監控每個接口的響應時間。簡單做法是在方法執行前後打時間戳計算,對於HTTP請求,也可以從access log中獲取接口執行時間。當然也可以用annotation來實現統一的執行時間監控。
-
執行異常數:指程序運行過程中發生的未捕獲處理的異常,一般是對場景考慮不周導致的異常發生,比如空指針、錯誤參數、數據訪問等的異常。 這些異常一旦發現,需要修複代碼邏輯。 異常在應用日誌中一般都會把錯誤堆棧打印出來。
4、數據庫監控
數據庫是大部分應用的核心和瓶頸,對其監控尤其必要。監控可以 在應用側執行,也可以在數據庫服務器上做。前者通過應用代碼中打印日誌來實現,或者直接override 鏈接池中相關方法來統一輸出日誌。在數據庫服務器上執行監控,需要根據數據庫的特點分別設計方案。以MySQL為例,可以通過監控其bin log來獲取執行的sql語句以及執行時間。使用Alibaba Canal 來對接MySQL的BinLog, 接收到BinLog消息後,解析消息數據,可以獲取請求的SQL、參數、執行時間、錯誤代碼等信息。
數據庫監控重點關注如下指標:
-
每秒請求數
-
慢查詢處理數
-
SQL語句執行時間
5、調用鏈監控
調用鏈監控指在微服務係統中,跟蹤一個請求從發起到返回,在各個相關係統中的調用情況。 調用鏈監控是跨係統的監控,需要在請求發起時分配一個可以唯一識別本次調用請求(或者成為事務)的ID,這個ID會被分發到每個調用上。之後在調用日誌中輸出該ID。當所有日誌都匯總起來後,可以從日誌中分析本次調用的流程。 對於HTTP/HTTPS請求,可以考慮將ID放到Header裏麵,這樣不會影響接口邏輯。
6、業務監控
業務監控是一個複雜的話題。這裏以支付為例,說明業務監控的架構和實現。
支付業務監控
每個支付通道監控包括如下內容:
-
支付通道接口請求數: 如果一段時間內接口請求環比大幅度下降,可能是該接口出現問題了。
-
支付通道接口請求失敗數,即調用接口失敗的數量。
-
支付通道接口請求延遲。
-
支付通道支付失敗率。每個通道支付有一定的失敗率,如果給定時間內突然有超過這個失敗率的情況出現,則可能是通道出現問題了。
-
支付通道同步、異步調用次數。
支付接口,如支付、提現、退款、簽約、訂閱等,監控如下內容:
-
總金額,如果總金額有大的波動,則有洗錢的可能
-
每筆平均金額
-
支付成功率
監控架構
實際上對一個業務來說,大部分係統監控的指標是類似的,而按照這種方式,每個指標在各個被監控係統中還需要單獨寫腳本實現,工作量大。針對這種情況,可以采用日誌集中監控的方式來處理。 考慮到日誌最終都需要歸並到一個日誌倉庫中,這個倉庫可以有很多用途,特別是日常維護中的日誌查詢工作。多數指標可以在日誌上完成計算的。 借助這個係統,也可以完成監控: !zabbix 監控。
日誌通過Apache Flume來收集,通過Apache Kafka來匯總,一般最後日誌都歸檔到Elastic中。 統計分析工作也可以基於Elastic來做,但這個不推薦。 使用Apache Spark 的 Streaming組件來接入Apache Kafka 完成監控指標的提取和計算,將結果推送到Zabbix服務器上,就可以實現可擴展的監控。
這個架構的優勢在於:
-
監控腳本的跨係統使用。 指定日誌規範後, 隻要按照這個規範編製的日誌,都可以納入監控,無需額外配置。
-
服務重新部署時無須考慮監控腳本的部署,所有監控直接生效。
難點在於,提煉一套通用的日誌規範,考慮如何通過Spark來分析日誌。
日誌收集
Flume和logstash都可以用於日誌收集,從實際使用來看,兩者在性能上並無太大差異。flume是java係統,logstash是ruby係統。使用中都會涉及到對係統的擴展,這就看那個語言你能hold住了。
日誌數據流
Flume和Logstash都支持日誌直接入庫,即寫入HDFS,Elastic等,有必要中間加一層Kafka嗎?太有必要了,日誌直接入庫,以後分析就限製於這個庫裏麵了。接入Kafka後,對於需要日誌數據的應用,可以在kafka上做準實時數據流分析,並將結果保存到需要的數據庫中。
日誌分析
Streaming分析,可以走Spark,也可以用Storm,甚至直接接入kafka做單機處理。這取決於日誌數據規模了。Spark streaming是推薦的,社區活躍度高,又集成了多種算法。
日誌係統與日誌框架
Java主流的日誌係統有log4j,JULlogback等,日誌框架有apache commons logging,slf等,關於這些係統的曆史掌故恩怨情仇八卦趣事,網上有不少資料,這裏不詳細介紹。
日誌係統選型
最好的編程語言是PHP還是Java? 同樣的,也有爭論:最好的日誌框架是slf還是commons-logging?最好的日誌係統是Log4j還是Logback?在使用上,它們的API和使用方式大體類似,slf有模版支持,但這也不是關鍵需求。而性能方麵,從我們測試用例中也沒有發現哪個係統或框架有明顯優勢。對性能有決定性影響的是使用方式。
日誌高能預警
根據我們的測試,在高並發係統中,關於日誌,有如下結論:
-
Log4j與logback在高並發下性能上並無太多差異,不用太糾結使用哪個API,.影響性能的是日誌內容的寫法和數據量。
-
輸出類名和行號會嚴重影響性能,這需要使用到性能不佳的反射機製。執行頻率高,性能要求高的代碼,禁用反射,禁用new操作。
-
高峰期係統出錯,如果打印錯誤堆棧,那絕對是雪上加霜,理由同上。
-
多線程時輸出日誌,寫鎖是影響性能的關鍵因素。緩解寫鎖的措施,首選加大日誌寫入緩衝區,其次是異步打印。異步對性能有提升,但不顯著。寫鎖出問題的一個現象是CPU跑滿。
-
原文發布時間為:2016-11-22 本文來自雲棲社區合作夥伴DBAplus
最後更新:2017-05-11 12:01:24
上一篇:
一條會施魔法的MySQL命令: STOP ALL SLAVES
下一篇:
MySQL實戰係列3:視圖、存儲過程、函數、索引全解析
數據中心傳統網絡向新網絡技術演進難題
CCAI | 如何能既便宜又快速地獲取大數據?這位微軟研究員設計了兩個模型,幫你省錢省時間
Selenium的PageFactory & PageObject 在大型項目中的應用
數據源ObjectDataSource的數據訪問類的編寫
FPGA資源平民化 - 阿裏雲FaaS使用指南
OSS WordPress插件(Aliyun OSS For WordPress)
存儲在U盤中的文件被誤刪後怎麼免費恢複
《數據結構與抽象:Java語言描述(原書第4版)》一2.1.1 類比
如何把關聯性的告警智能添加到 Nagios 上?(2)
黑客利用安卓主密鑰漏洞在華傳播病毒