支付微服務系統的基礎設施建設
基礎設施是為了支持支付開發的軟件過程。在進入主題之前,先吐槽下軟件過程。軟件過程在這幾年都越來越不受人待見了。在一些互聯網公司里面,軟件過程的概念往往被等同于拖拉、延期、冗長。他們為自己的軟件過程往往都會貼上敏捷的標簽,并為各種混亂的管理提供了一個非常好的借口。就算是先寫代碼再補需求,也能夠套上敏捷開發借口。可是這一套路,拿到金融軟件,特別是和錢打交道的支付系統開發上,卻是行不通的。且不用說混亂的管理滋生的各種漏洞容易吸引各路攻擊者,為了對接各個銀行渠道,他們也會要求開發商遵守一些底線。事實上,在各大互聯網和第三方支付公司,支付系統的開發一直都執行最嚴格的流程管理。那在公司各個項目之間的巨大的內部競爭壓力下,支付系統開發人員也不好意思說,我們執行的是最嚴格的軟件過程,所以系統升級慢。那如何在保證流程質量的前提下,在確保系統不斷演化升級的同時,提升系統質量,避免漏洞,降低風險呢?
從案例開始
那支付系統開發過程有別于其它系統的要點在哪?就目前大部分公司而言,一般系統的開發人員是所謂的全棧工程師的:從寫前后端代碼,測試,上線到運維。線上出現bug,就登陸到服務器上翻日志,找原因,或者直接到數據庫上改個數字??蛇@些行為,對支付系統來說,都是大忌。 介紹一個真實案例,某游戲公司的技術合伙人在開發時,將一些偏遠省份的收單賬戶替換成自己賬戶。一年多時間無人發現。直到有一天一位投資者去某省出差,使用這個系統執行支付時候,發現收款公司名稱與原公司略有不同。這位細心投資者讓公司調查一下這事情,才發現其中的貓膩。
開發人員把某個收款賬號替換成自己的賬號怎么辦?會不會修改數據庫,把自己賬號余額多加幾個零?這些都是真實存在的問題,也都有人干過。雖然人與人之間的基本信任還是需要的,可是支付系統的基礎向來都不是基于信任的,而是從各個角度來以最大的惡意來揣摩人性,從而出現可以被人利用的漏洞。 所以,對支付系統的開發,通俗的來說,有這個要求: 開發不上線;上線不開發。也就是開發人員不能參與上線和線上系統的運營。 那在這種情況下,如何保證開發的系統能夠順利上線,如何保證線上的系統在有問題的時候能夠盡快被診斷出來并解決? 這就需要一系列的基礎設施的支持。
微服務和自動化
傳統的軟件過程一個大問題是各個階段都需要人工干預。 而微服務架構的引入,其思想是通過降低系統的復雜度來使得過程的自動化成為可能。對此,Martin Fowler首先提出了在極限編程(敏捷)中使用持續集成的觀點。在微服務架構之后,由提出了持續交付的概念。 微服務架構如何支撐這些過程,可以參考相關資料,本文不再詳細介紹。 而從支付系統的角度,它的基礎設施建設有什么不同之處?如果從微服務的角度來考察,和其它業務系統開發并無不同之處。無非是要求更嚴格罷了。構建的原則也是.”人管代碼,代碼管機器。通過流程自動化,逐步消除軟件過程中的人工干預,加快迭代,提升質量。
怎么度量支付系統基礎設施建設的成熟度?我們沒法從部署了多少個軟件,使用了多少臺機器這樣硬性指標來考察。敏捷開發的一些最新理念可以幫助我們定性地度量這個進度。 軟件開發過程包括編碼,構建,集成,測試,交付(預發布),部署。我們可以從這流程的自動化程度來度量基礎設施建設的階段。
持續集成、持續交付和持續部署,分別對應自動化軟件過程的三個階段。持續集成實現了編譯、發布、集成編譯的自動化,并最終自動部署到集成測試環境。在測試完成后,需要人工驗證和上線。 而持續交付則更進一步,在實現自動測試基礎上,能夠實現自動部署到預發布環境。在準線上環境確認達到可以上線的要求后,人工部署到線上環境。 持續部署是自動化的最終目標,開發完成后,能夠自動地完成驗證并實施到線上的系統。
不管是哪個階段,都需要自動化的基礎設施的支持。這里分頭介紹其中主要的基礎設施軟件,以及他們的選型。
版本控制
版本控制所有自動化工作的基礎。國內大部分公司已經完成了從subversion到git的改造,git也成為版本控制的標配了。支付系統在版本控制上和其他系統并無太多的差異。這里需要介紹的是針對微服務架構的版本控制。 我們知道對版本控制來說,代碼合并是一個很難避免的噩夢。 而微服務化可以很好的解決這個問題,由于服務的粒度小,每次變更一個人就可以搞定。每個服務有都可以獨立上線,避免修改沖突。 這樣版本控制就相對來說比較簡單:
代碼審核
支付系統的每一行代碼都要執行審核!代碼審核對支付來說意義重大,是避免惡意代碼不可缺少的一個環節。 一般來說,支付代碼要求至少是2人審核通過。代碼需要執行日常審核,而不是到快發布時的統一審核。審核的工具一般是需要和版本控制相集成的。 subversion上用reviewboard, git上用gerrit或者gitlab。雖然說gitlab是比較新的系統,不過還是推薦gerrit,可以強制代碼審核以及控制代碼審核流程,確保兩個人都OK后才能入庫。
對于使用gitlab的系統而言,它的優勢在于可擴展性強。gitlab默認不支持強制代碼評審。但如果不強制執行代碼評審,那會出現開發人員未經code view就提交自己merge代碼。而reviewer 未能夠及時review代碼,也會影響進度。此外,開發人員沒有執行代碼審計(sonar)就提交代碼,也是常見的事情。 好在gitlab有非常好的可擴展性,通過webhook可以根據需要實現各種額外功能。 webhook是gitlab的一個擴展點,通過用戶提供的回調HTTP請求來監聽git的push、comments、merge等事件。比如可以要求必須至少兩個LGFM(LooksGoodForMe)才可以merge。通過webhook來監聽comments,匯總兩個LGFM之后,自動將代碼merge到trunk上。
代碼審計
或者說是靜態代碼審查。Apache PMD, FindBugs都是常用的工具,推薦用Codehaus Sonar系統,即可以實現和Maven的集成,也可以有Web UI可以查看代碼質量。提供的審核規則也比較全面,并且可以根據公司的需求來定制。
日志搜集與分析
開發同學不碰線上系統,這是支付系統的原則。那線上系統出問題了怎么辦?開發人員總是依賴日志來排查問題,一個日志匯總系統是支付平臺必備的基礎設施??紤]到日志最終都需要歸并到一個日志倉庫中,這個倉庫可以有很多用途,特別是日常維護中的日志查詢工作。多數指標可以在日志上完成計算的。 借助這個系統,也可以完成監控:
日志通過Apache Flume來收集,通過Apache Kafka來匯總,一般最后日志都歸檔到Elastic中。 統計分析工作也可以基于Elastic來做,但這個不推薦。 使用Apache Spark 的 Streaming組件來接入Apache Kafka 完成監控指標的提取和計算,將結果推送到Zabbix服務器上,就可以實現可擴展的監控。 Apache Flume和Logstash都可以用于日志收集,從實際使用來看,兩者在性能上并無太大差異。Flume是java系統,Logstash是ruby系統。使用中都會涉及到對系統的擴展,這就看那個語言你能hold住了。 Apache Flume和Logstash都支持日志直接入庫,即寫入HDFS,Elastic等,有必要中間加一層Kafka嗎?太有必要了,日志直接入庫,以后分析就限制于這個庫里面了。接入Kafka后,對于需要日志數據的應用,可以在Kafka上做準實時數據流分析,并將結果保存到需要的數據庫中。
系統監控
現在基本上 Zabbix 成為監控的標配了。 一個常規的 Zabbix 監控實現, 是在被監控的機器上部署Zabbix Agent,從日志中收集所需要的數據,分析出監控指標,發送到zabbix服務器上。
這種方式要求每個機器上部署 Zabbix 客戶端,并配置數據收集腳本。Zabbix的部署可以作為必裝軟件隨操作系統一起安裝。
持續集成
毫無疑問,Jenkins就是CI的不二之選。 但是這也只是一個工具,怎么用還得結合業務來實現。而上面列出來的這么多工具和使用要求,如何確保開發人員安規范來實現,并且盡可能地自動化,一個解決方案就是用集成工具將這些活動串起來。這里不詳細介紹Jenkins的原理或者它和hudson的恩恩怨怨,重點描述如何使用。 Jenkins使用的要點是設置各個Job。而Job的設置,又分為線上和測試的Job。測試環境的Job分為 部署、啟動、停止三個群組。線上分為 預部署、部署、啟動和停止四個群組。 在每個群組中,每個項目對應一個可執行Job。
在測試環境部署執行如下工作:
- 獲取受控代碼。如果有指定版本號,則下載該版本號對應的代碼;否則獲取最新的Tag分支并下載該代碼。集成是必須從代碼開始構建,目的是保證線上運行的系統和版本控制服務器上的代碼是一致的,而不是從某人機器上修改后的代碼直接傳上去的。 如果出現問題,只要獲取該版本的代碼即可定位到出問題的地方;
- 執行代碼審計
- 執行maven deploy命令,執行編譯、單元測試、版本發布等工作。 注意,這個階段發布的包,都是SNAPSHOT版本的包。
- 生成javadoc, 接口文檔,發布到測試服務器上,測試人員將對這個文檔做驗證。
- 生成單元測試覆蓋率報告、代碼質量報告。
- 發布系統到測試環境上。
在線上環境部署執行如下工作:
- 如果有指定版本號,則下載該版本號對應的代碼;否則獲取最新的Tag分支并下載該代碼;
- 執行mvn setVersion命令, 將所有SNAPSHOT版本依賴修改為正式版本依賴。
- 執行代碼審計
- 執行maven deploy命令,執行編譯、單元測試、版本發布等工作。 注意,這個階段發布的包,都是RELEASE版本的包。
- 生成javadoc, 接口文檔,這是正式版本的文檔。
- 發布系統到線上環境上。
以上支付系統中涉及的主要的基礎設施,本文僅完成初稿,后續將會逐步再完善其他的基礎設置。 也歡迎大家補充完善。最新的修訂版本,請點擊“查看原文”來獲取。
【本文為51CTO專欄作者“鳳凰牌老熊”的原創稿件,轉載請通過微信公眾號“鳳凰牌老熊”聯系作者本人】