1. 程式人生 > >網易寶系統架構之我見:高可用篇

網易寶系統架構之我見:高可用篇

此文已由作者王文學授權網易雲社群釋出。

歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。


網易寶支撐了整個集團業務絕大部分的支付場景,平均每天的支付訂單有100萬單,接近1億的交易額。對系統的可用性要求極高。下面就從我的理解上說說網易寶的系統是如何實現高可用的。


1. 網易寶系統的整體架構

先看看網易寶的系統整體架構(16年初的架構)


                             fac7a2e9-8ba5-4c92-96e7-b1cbb6fbc01c?imageView&thumbnail=980x0

                                                              網易寶目前系統整體架構圖

 

中間大的淺藍色的部分為網易寶系統的整個體系。按照從下到上的層次關係分為儲存層、技術元件、服務層、接入層。每個層都有系統監控來監控系統的狀態。服務層和接入層有風控系統來監控風險行為,保障使用者資金的安全。

儲存層:資料庫主要使用Oracle。網易寶的核心支付服務是基於本地事務去保證資料強一致性的。使用者支付完成,訂單狀態修改為成功,扣除餘額,產生資金流水,需要強一致性的保證。訂單和流水的資料佔了網易寶資料庫業務資料的絕大部分。Oracle在單機大表的效能上是非常高的。所以資料庫採用的Oracle。檔案儲存主要使用的FTP。用於存放銀行清算檔案、對賬檔案、結算檔案。

技術元件層

:包括dubbo分散式遠端呼叫中介軟體、訊息佇列中介軟體kafka、 分散式應用程式協調服務Zookeeper、分散式快取儲存memcached、杭研排程系統、linux-crontab(逐步遷移到杭研排程系統上,後續廢棄)

服務層:為網易寶的核心層,提供高內聚的服務。網易寶支援多樣化的支付需求是通過組裝服務層的服務來完成業務流程的。包括使用者賬戶服務,訂單查詢服務,支付核心服務(實現了實名,綁卡,充值,支付,提現,退款的核心流程);閘道器服務payments-trans接入了幾十家銀行和其他支付通道;積分服務提供積分紅包的充值、提現、發放和消費服務;閘道器路由服務gate-service提供支付時路由到具體的支付通道的服務;sign-service提供簽名服務,保證內部系統之間和外部系統的呼叫請求的安全性;pay-gate提供第三方支付通道的對接服務;platform-module提供商戶資料的查詢服務。接入服務層的服務的方式包括dubbo,http,依賴jar元件。對賬中心和結算中心不參與使用者支付的流程,對賬中心支援所有銀行通道的對賬,核對我們的備付金和使用者商戶的賬戶資金完全無誤, 對網易寶的資金流水按會計分錄做到日切,符合人行的監管要求。結算中心給商戶提供人民幣結算服務和外幣結算服務。

接入層: 分為前臺系統(介面互動, 後臺API介面)和管理後臺系統。 前臺系統包括使用者前臺epay-web、收銀臺cashier(從epay-web拆分出來,正在開發中)、網易寶使用者端APP、可嵌入第三方APP的支付SDK元件、活動系統promotion、商戶前臺系統platform-web。 管理後臺系統包括後臺管理epay-admin、閘道器管理payments-admin、商戶後臺管理platform-boss(正在開發中)。

風控: 對使用者在網易寶的整個行為做風險控制,保障使用者賬號和資金的安全。風控通過kafka非同步方式同步網易寶的業務資料,運用大資料處理技術做分析。

與網易寶接入層人機互動的有使用者、商戶、後臺管理人員(技術支援&客服&財務),商戶的應用(遊戲、 考拉、一元奪寶、郵箱、理財等)。

網關係統和對賬中心後臺依賴幾十家銀行的閘道器。

以上對網易寶的整個體系架構按照層次做了個簡單的介紹,下面進入主題,網易寶系統是怎麼實現整體系統的高可用性的。


2. 系統高可用性的分析

2.1 叢集部署、負載均衡、備份(消除單點問題)

網易寶的所有核心應用和中介軟體都是叢集部署的,通過負載均衡,平均分配流量。

對於業務系統, 在nginx伺服器(nginx叢集部署,負載均衡使用LVS)上配置了負載均衡策略,路由請求到後端的應用伺服器resin。如果web應用叢集某臺機器掛了,nginx通過心跳健康檢查,3秒內能檢測到,把這臺機器從可用列表中剔除出去。

中介軟體dubbo的consumer基於負載均衡演算法, 獲取zookeeper上統計的provider的負載情況,決定請求哪臺provider。Kafka也是類似的原理。如果dubbo服務的某臺provider掛了,與provider維持長連線的zookeeper心跳執行緒會檢測到,把provider從服務的可用provider列表中剔除,並快速通知到所有依賴該服務的consumer(也是維持的TCP長連線),consumer更新本地快取的provider列表。

對於有狀態的伺服器,都有資料備份機制。

資料庫主庫會非同步同步資料到備庫。資料庫主庫掛了,如果切到備庫,可能會丟失部分業務資料(非同步複製,網路穩定情況下10ms以內的延遲,不是同步寫多份的)。Kafka每條訊息都會複製到不同的機器(broker)上。Zookeeper上的資料也是多寫的。Kafka的主broker掛了或者zookeeper的主伺服器掛了,通過選舉演算法選舉出新的leader。Leader用於讀寫,slavers用於備份。Leader掛了,從slavers中選舉出新的leader快速恢復服務。Kafka和zookeeper是做了資料高可靠性保證的,極小概率會出現丟失資料的情況。

多機房部署上,網易寶有杭州、北京兩地機房。杭州是主機房,北京是備,不是多活的。 北京的機房伺服器數量較少,資料庫伺服器效能較差,資料複製也有秒級的延遲。所以不到萬不得已,是不會切到備用機房的。目前網易支付已經在搭建義橋的機房,2017年實現濱江機房和義橋機房的雙活,解決機房的單點問題。

綜上所述,在同一個機房,網易寶無論是無狀態的伺服器,還是有狀態的伺服器,從儲存層,到中介軟體層,到應用層,都不存在單點問題。機房的單點問題也會在不久後解決。


2.2 快取:空間換時間

更新不頻繁的基礎熱點資料,如配置項、所有商戶資訊、閘道器資料,在應用啟動時,載入到本地快取。減少對資料庫的頻繁呼叫。


2.3  應用無狀態化,支援橫向擴充套件

網易寶的session管理使用中心化的memcached叢集,業務流程中的一些狀態資料,也是存放到memcached。系統之間使用檔案資料互動的,檔案儲存到FTP。需要持久化的業務資料儲存到中心化的資料庫。 不管是業務資料,還是非業務資料,都不會儲存到本地應用伺服器,保證應用無狀態化,使得應用叢集可以快速的橫向擴充套件。


2.4 讀寫分離

為了保證核心支付服務的穩定性,資料庫上做了讀寫分離。核心業務的讀寫走主庫。對於讀實時性要求不高的查詢場景,查詢備庫。如商戶系統訂單的查詢請求。對於耗時長的sql的查詢場景,查詢異構庫,如商戶的對賬單下載。


2.5 非同步化

  • 熱點賬戶處理非同步化

為了避免熱點賬戶上的行鎖的激烈競爭影響系統吞吐,網易寶對熱點賬戶的餘額更新和資金流水生成,做了非同步處理。業務完成後如果需要變動熱點賬戶的金額,先生成緩衝流水,然後由排程任務非同步去消費緩衝流水去更新餘額、生成資金流水。使熱點賬戶的併發鎖競爭變成了序列處理,大大降低了行鎖競爭導致的執行緒阻塞,提高了系統的吞吐。

  • 提現、退款處理非同步化

提現、退款處理對實時性的要求不高,通過非同步化,對於處理失敗的訂單可以用重試機制補償。避免了同步呼叫失敗給使用者不好的體驗。


2.6 系統拆分解耦、核心程式碼多版本歸一

早期的網易寶只包括epay、epay-admin、payments、sign幾個系統。 大部分的業務功能都集中在epay一個應用裡。epay應用非常的龐大,包含了使用者前臺、收銀臺、積分紅包、活動、商戶前臺功能、API、風控、資金對賬監控。存在以下幾個問題:

a.核心業務功能和非核心業務功能在一個系統裡,程式碼緊耦合,並且公用伺服器資源,非核心業務功能出現問題容易影響到核心業務功能。

b.在一個應用上大量的分支並行開發feature,合併程式碼容易衝突。應用的一次釋出包含幾十個feature。一個feafure釋出出問題,釋出回滾,導致其他feature也一起回滾了。造成開發效率和釋出效率低。

c.epay系統經過幾年的業務和技術選型升級,遺留下程式碼多套並存的問題。一個需求的變更,可能需要從上層到下層,改動多套程式碼。核心程式碼的多套並存、低內聚,程式碼難以維護,使開發的工作量變大,並且容易出bug。使後續的系統拆分,服務化改造困難重重。


為了提高系統的整體可用性,提高大家的工作效率,針對以上幾個問題,網易寶在過去的一兩年裡做了很多的重構改造工作。包括以下幾個方面:

2.6.1 系統拆分

  • 積分紅包底層service從epay中拆分出來,獨立jifen系統,提供服務化的介面。

  • 活動功能從epay中拆分出來,獨立promotion系統,提供活動業務功能。

  • 風控模組從epay中拆分出來,獨立risk系統,提供限額服務、黑白名單服務、反洗錢監控、使用者風險評級。

  • 閘道器路由模組從epay中拆分出來,獨立gate-service系統,提供閘道器查詢和路由支付、提現通道的高可用服務。

                        093dc8c8-07ba-43ec-b9c3-41953743c0fa


                                               Epay與閘道器路由服務的呼叫關係

 

  • 商戶前臺系統從epay中拆分出來,獨立platform-web系統,提供商戶的業務功能。


                    5f0c3d10-acd4-4d8e-aa33-4af7fddb69ea
                                                 商戶系統模組依賴關係圖

 

2.6.2 程式碼重構

  • 底層核心程式碼消除多個版本,統一為一個版本實現,內聚化。


                          c713da15-8543-46b9-a14d-167bd58bcd88
                           83e2b501-1fb2-4b1a-b5fa-e4528b084ba7
                                                      epay核心程式碼內聚歸一

 

  • epay按層次拆分為多個子工程,底層子工程可以打包為公共jar元件,也可以包裝為服務化介面。


                                 6cf03735-0cae-4f05-80b5-71e4cf2d6ea8


                                                    Epay子工程拆分依賴關係圖

 

3. 總結

提高系統的可用性非一蹴而就,只有深入的理解業務,梳理清楚業務流程和依賴關係,工作中不斷的發現系統的痛點,逐個解決,步步為營,系統的整體可用性才能上一個臺階。


網易雲免費體驗館,0成本體驗20+款雲產品! 

更多網易技術、產品、運營經驗分享請點選


相關文章:
【推薦】 最小化區域性邊際的合併聚類演算法(上篇)
【推薦】 【專家坐堂】四種併發程式設計模型簡介
【推薦】 用供應鏈管理思路降低教培產品成本