破繭化蝶:中郵消費金融系統服務化和容器化實踐
消費金融是近年來新興的熱門行業,市場廣闊、需求量大、行業競爭激烈。為了突破傳統金融行業限制,建立一套靈活、高效、可靠的消費金融系統,支持互聯網環境下高並發訪問、可靠資金交易、互動式場景化的需求,中郵消費金融從基於集中式商業中間件搭建的傳統信貸系統,演進為基於微服務、分散式、靈活快速迭代的互聯網消費金融系統。
在 2018 年 12 月 7-8 日北京 ArchSummit 全球架構師技術峰會上,我們邀請到了中郵消費金融 IT 運營部總經理助理 & 架構師 李遠鑫老師從服務化和容器化兩個方面剖析中郵金融系統的迭代更新。
服務化演進
開業初期,為了能夠迅速把 IT 系統搭建起來,支撐公司的業務開展,我們基於集中式的商業中間件構建了一套傳統的金融信貸系統,涵蓋了貸前、貸中和貸後管理,採用的是煙囪式架構,屬於傳統的交易型 IT 系統,這樣的架構在業務高速發展的過程中顯得開發迭代更新效率低下、創新困難、難以擴展,形成數據孤島。為此,我們採用了「大中台、小前端」的中台戰略,將應用架構設計為渠道、應用、共享服務中心和基礎技術平台四個層次,其中共享服務中心按照業務領域來劃分,盡量將原有的業務功能進行解耦,沉澱出公共部分,採用微服務的方式進行構建,整個系統架構也由原來的集中式架構轉變為分散式的架構,不僅提升了系統的整體性能和可擴展性,也使新業務和新產品的開發效率有了明顯的提升。本次主題的第一部分將分享中郵消費金融從煙囪式系統向多個共享服務中心演進的服務化實踐。
分散式技術平台的搭建
共享服務中心建立在分散式技術平台之上,主要包括服務調用和治理框架、消息中間件、緩存、分散式文件系統、分散式資料庫等。這裡重點介紹服務調用、消息中間件和應用配置中心的搭建情況以及分散式事務處理的方案。
(1)在服務調用框架方面,我們早期對 DubboX 進行了裁剪和優化封裝,作為主要的微服務開發技術,後續逐漸以 Springboot+Jersey 提供 Restful 服務、SpringCloud 替代,阿里巴巴恢復對 Dubbo 的支持,我們也計劃將部分原來通過 DubboX 開發的服務遷移到目前的 Dubbo 版本。同時基於企業內部微服務體系的逐步龐大,服務的有效治理也成為了我們逐步關注的重點,通過對比和研究業界的成熟方案,以及結合我們自身的系統設計。我們最終選擇了 Zookeeper 作為我們服務治理中心,即基於 Zookeeper 的 Dubbo RPC 服務與基於 Spring Cloud Zookeeper 的 http 服務管理並存的服務結構。
隨著應用越來越多,系統之間的調用關係也越來越複雜,對服務的調用進行全鏈路跟蹤和監控非常有必要。對此,我們通過 Java Agent、Byteman、OpenTracing 等技術構建了自動的日誌監控埋點,基本不需要應用程序改動即可將日誌埋點嵌入,從而形成完整的微服務調用鏈路,再通過日誌搜索和圖形化展示,可以實現對微服務的有效監控。
(2)消息中間件的選擇。消費金融的特點是前端進件的業務量和並發量較大,但是大部分交易不需要強實時的響應。為了把大部分服務解耦,提升系統的吞吐率和性能,需要實用消息中間件技術。根據消費金融的特點及公司業務定位,要求消息隊列必須是高可用,高性能且自主可控的,從社區的活躍度、消息堆積能力和性能來看,Kafka 更適合於我們的場景。另外,大數據處理和運維監控大部分消息隊列也需要用到 Kafka,為了統一消息隊列標準,便於維護,我們最終選擇了 Kafka 作為消息中間件。
Kafka 在操作系統崩潰時可能會存在消息丟失的情況,當然在 Kafka1.0 版本以後,得到了比較大的優化。早期,為了保證消息的可靠投遞,我們基於 Spring Kafka 冪等發送和支持事務等特性確保消息發送成功,自實現了消息多線程處理及 Offset 管理,引入 Redis 緩存 Offset,支持應用異常時從 Redis 恢復消息進行重新處理,實現 At-least-once 消費語義。
在 Springboot 2.0 發布後,消息消費通過 Spring Cloud Stream 支持 Partition 數據應用實例數及每個實例的並發數自動創建擴容,實現對每個 Partition 消息的單線程、冪等處理及整體上的多線程並發處理,Offset 通過 Spring Kafka 自動管理,實現 At-least-once 消費語義。另外很重要的一點,為了確保 At-least-once,消費端必須實現冪等性。通過優化和有效的異常處理機制,我們的系統沒有出現消息丟失的情況,而且具備較高的吞吐率,達到了預期的效果。
(3)消息醫院。使用 Kafka 消息中間件的服務必須要考慮消費端應用異常時如何進行處理,我們早期的做法是擴展 Spring Kafka,當消息消費出現異常時,將異常消息統一送進一個異常處理 topic,由各應用自己監聽異常 topic 並進行相應的處理,例如重試、丟棄等。為了使消息的異常處理形成統一標準, 簡化異常處理,減少重複開發,我們自研實現了一個消息醫院(名稱來源於 Sam Newman 的《微服務設計》,也稱為死信隊列),將所有異常消息都發送到消息醫院中,通過一個管理端界面來查看異常消息列表,設計一定的異常處理策略(如定時自動觸發一定次數的重試、手工重試或直接丟棄等),作為 at- least-once 消息投遞保證的必要措施。
(4)分散式事務處理。分散式事務處理的常見解決辦法是兩階段提交 2PC、補償事務、TCC、基於消息的可靠事件機制。消費金融的大部分場景不需要保證強一致性,只需要保證最終一致性即可,TCC 模型過於複雜,而且可能會存在讀臟數據或者中間事務狀態不一致的問題,鑒於消費金融的事務大部分複雜度不高,並且可以通過場景化和多交互步驟的方式避免分散式事務,我們主要選擇了可靠事件機制,通過消息的可靠投遞實現最終一致性。
分散式事務處理是一項複雜的研究課題,目前沒有非常完美的解決方案。分散式事務處理的關鍵,在於進行系統設計時,首先分析清楚強事務是否是真正的需求(例如轉賬),如果強事務不是真正需求,則應該通過場景化設計來盡量避免產生分散式事務。由於微服務實施後,無法通過場景化弱化事務的情況下(例如跨共享服務中心的多服務調用),應避免採用兩階段提交,盡量採用基於消息的可靠事件機制保證最終一致性。對於跨越內部系統和外部系統的分散式事務(如放款記賬和銀聯代付),目前沒有很好的解決方案,只能採取補償事務、冪等重試的方式解決,在進行系統設計時,應遵循良好的設計原 則,確保補償機制和重試機制足夠合理和健壯。
(5)應用配置中心。在微服務架構中,服務之間有著錯綜複雜的依賴關係,每個服務都有自己的依賴配置,在運行期間很多配置會根據各種因素進行動態調整,傳統的配置信息處理方式是將配置信息寫入 xml、.properties 等配置文件中,和應用一起打包,每次修改配置信息,都需要重新進行打包,效率極低;同時在分散式應用場景下,配置的批量更新,灰度發布,集群管理、設置回滾、審計日誌等開發與運維需求也對配置信息的管理提出了更高的要求。因此,我們開發了一個適用於各個應用系統、實現配置集中管理、支持信息實時更新等功能的配置應用中心。應用配置管理系統的使用,不僅使得配置信息能更統一、更有效的集中管理,同時也降低應用系統代碼的耦合,使得開發、測試人員以一種更靈活的方式對環境、場景進行管理。
微服務集成及容器化演進
隨著共享服務中心和微服務的不斷擴充和完善,應用層與微服務之間、微服務之間的調用關係會面臨變得越來越複雜的情況,如果不加以管控,會變成蜘蛛網式的調用,應用程序開發也會變得越來越複雜。為此,我們引入了微服務統一運營平台的概念,目的是將微服務在線化和可視化,對微服務進行集中管理,通過容器技術提供微服務快速組合和擴展的能力,達到業務流程的快速落地和調整,實現業務的高效拓展,另外,平台還可以對微服務組合出來的應用程序進行全面的監控和數據稽核。
首先是服務的在線化。將各共享服務中心提供的服務註冊到統一運營平台的服務註冊中心,註冊中心提供一個可視化的界面,業務和技術人員可以方便地檢索現有的共享服務,查看其用途、介面規範和目前正在使用該服務的應用。我們主要以 CDC 的模式(Consumer-Driven Contracts,消費方驅動的契約開發方式,是指從消費者業務實現的角度出發,驅動出契約,再基於契約,對提供者驗證的一種測試開發方式)進行了服務介面的規範化約束,確保了開發流程的高效性和正確性。
其次是服務的集成。傳統的服務組合和集成有兩種方式:編排和協同,其中編排的方式一般是通過 ESB 或工作流引擎進行統一配置和管理,有明確的流程,由一個中心大腦控制;協同是事件驅動的方式,每個系統收到信號後啟動處理,職責分明,細節獨立,系統模塊間的耦合度低。我們選擇了基於事件驅動的協同方案,首先通過將現有的微服務以代理服務的方式註冊到 SpringCloud DataFlow,並以可視化拖拽的方式對各種代理服務進行流程設計,通過服務間的組合串聯來完成業務流程。串聯的微服務之間的數據傳遞是通過事件驅動的模式進行,即通過 kafka 非同步消息的模式,並通過消息醫院和事後補償機制進一步確保事務的最終一致性。
接下來是容器化。在系統應用微服務化的背景下,運用 Docker 技術棧將應用容器化成為了我們的目標。容器技術為實現更高效的資源利用,更快速的交付和部署,更輕鬆的遷移與擴展和更簡單的更新管理提供了可能,同時也更適應快速變化的市場和業務需求。在應用容器化進程中,我們運用 Docker 技術對不同的微服務應用打包成相應的鏡像,並將 Docker 鏡像發布到私有鏡像倉庫統一管理。同時運用 Kubernetes 對容器和微服務進行編排和管理。
在服務集成運行環境方面,前面提到的服務在線化,向業務和技術人員展示的實際上就是集成 Docker 鏡像倉庫形成的微服務應用商店,通過可視化界面實現對微服務的參數動態展現和進行設計配置,Kubernetes 會根據設計過程生成的配置文件到 Docker 倉庫獲取相應鏡像,部署到容器節點中,形成所需的服務,利用 Docker 和 Kubernetes 的特性,服務可以實現高可用、自動負載均衡、失效重建以及自動擴展。
最後,金融系統追求的是賬務的準確性,需要對組合服務開發的應用進行業務稽核。業務稽核模塊以業務為維度登記業務及其檢驗規則,實現統一應用系統的抽樣數據收集,對抽樣數據進行樣本聚合,並根據設置的檢驗規則進行校對和檢驗,對校驗異常的數據進行預警,並提供統一的監控界面。
本部分會以其中一個真實具體的業務模型為例介紹服務集成的實例,預覽如下:
作者介紹
李遠鑫,中郵消費金融有限公司IT 運營部 總經理助理 & 架構師。曾參與中國郵政儲蓄銀行全國中間業務平台、儲蓄系統邏輯大集中等大型金融項目,曾任中郵消費金融公司軟體研發高級總監,現任 IT 運營部總經理助理、架構師,負責中郵消費金融公司等 IT 系統規劃和架構設計,並帶領團隊完成從基於集中式商業中間件的金融交易系統向靈活、可靠、高性能、分散式的微服務消費金融交易系統的演進,在 2017 年支付寶 66 信用日活動中支撐日均 10 萬的交易量和 30 萬 PV 峰值。
歡迎大家來 12 月 7 日北京 ArchSummit 會議上聽我的分享,希望和大家有更多的交流探討。掃碼查看會議的其他演講內容,本周是 8 折最後一周,購票可以聯繫灰灰姑娘 17326843116


※領導要我做管理,掐指一算,發現事情不簡單
※百萬年薪架構師豐富技術「儲備庫」的四個方向和三個熱點
TAG:InfoQ |