華泰證券:如何自研高效可靠的交易系統通訊框架?
一、引言
華泰證券自研交易系統經過近兩年的建設,取得了階段性的成果,並在線上為華泰自營部門和部分機構客戶提供了優質的服務。本文對自研交易系統的通訊框架進行總體的介紹。
首先,我們以委託(交易下單)這個最普通的場景為例,大致觀察下資料是如何在系統內部流動的。如圖 1,客戶端從下單到接收成交回報,資料大致流經了閘道器、OMS(訂單管理系統,以下簡稱 OMS)、DownStream(報盤)、訂閱中心。
看似簡單的資料流,在專案設計和開發的過程中,我們自己、業務後臺,提了很多的問題,比如:
1)客戶端與閘道器間通訊的安全如何保障?如何避免使用者感知鏈路的通斷?
2)成交回報如何快速回到客戶端?
3)業務系統只想關注於業務邏輯,不關注許可權的控制,可行嗎?
4)OMS 是記憶體交易系統,為了解決使用者規模問題,需要基於分片水平擴充套件,高可用方案需要支援分片內的主備機切換,通訊框架可以支援這些需求嗎?
5)DownStream 有多個節點,這些節點面向不同的報盤物件,如櫃檯、交易所等,可以對上游的使用者(OMS)遮蔽這些差異嗎?
6)部分應用沒有狀態,可以平行擴充套件,消費者可以負載均衡地訪問我們的應用,可以嗎?
7)是否可以支援灰度升級?
帶著對這些問題的探索和解決,我們來介紹自研系統的通訊框架。
二、通訊框架
我們先給出系統整體的示意圖(如圖 2 所示),然後介紹我們通訊框架的核心組成部分。
外部系統訪問交易相關的任何後臺服務,需要通過 NGINX 代理,訪問相應的閘道器服務組,通過閘道器路由到相應的後臺系統。內部訪問交易相關後臺服務時,通過 XSTEP 的服務發現機制,直接對目標服務發起訪問。
2.1 XSTEP 協議
2.1.1 協議分層
XSTEP 協議是自研交易系統內部採用的協議,為了與 Dubbo 更好的相容,我們將 XSTEP 協議進行了分層設計,由會話層和應用層協議兩部分組成。業務系統可以在會話層與應用層皆使用 XSTEP 協議,也可以會話層使用 Dubbo,應用層使用 XSTEP。
2.1.1.1 會話層協議
會話層協議採用了輕量級的設計理念:信任 TCP 的可靠傳輸能力,正常情況下可以保證訊息的完整與順序,當出現異常情況時(如協議型別異常、校驗異常),代表網路環境異常,會話層中斷重連,不嘗試進行訊息的重傳。
會話層規定 T 為標準空閒間隙,3 個間隙未有任何報文傳輸,需要中斷鏈路。XSTEP 會話層在實現時,提供了鏈路空閒自動心跳的能力。為了防止惡意攻擊或資料異常跳變引起的通訊異常,XSTEP 會話層規定了最大報文長度,超過此大小的報文會被丟棄。
會話層在實現時,支援自動重連,支援自動重連策略的設定。同時為兼顧安全與效率,會話層支援非加密方式傳輸和 TLS 加密方式傳輸,應用可以根據應用場景自由選擇。
會話層還提供了服務發現與路由的能力,將在 2.1.2 節中介紹。
2.1.1.2 應用層協議
XSTEP 應用層協議定義了資料在記憶體中的組織形式,並通過統一的資料結構,提供資料的訪問介面。
Event 資料結構的定義如圖 -3 所示。資料結構通過 MAP<K,V> 鍵值對的方式作為基本的資料儲存結構,介面上,支援所有的基礎資料型別。
同時為了支援陣列及巢狀結構,還提供了 Group 資料結構(如圖 -4),該結構支援巢狀定義,形成無限擴充套件的樹形結構。上述資料形式的定義,在實踐中可以滿足目前所有業務的資料形式。
2.1.2 服務發現與路由
協議設計過程中,我們定義了幾個原則:1)服務的消費者不應感知具體服務提供者的變化 2)要支援服務的負載均衡訪問 3)要支援服務的主備訪問 4)要支援服務分組,以隔離不同的使用者或業務或版本,並支援服務的灰度升級 。
基於上述目標,我們設計了服務的自動釋出與發現機制,並設計了兩級路由。通過 XSTEP 開發包開發的應用,啟動後將會自動釋出到註冊中心。
2.1.2.1 服務釋出
註冊中心包含多級目錄,頂級目錄 XSTEP 表示這個一個 XSTEP 應用;第二級目錄為系統名;第三級目錄區分了服務的提供者和消費者,同時該級提供了一個名稱為 router 的固定檔案,用於系統自定義分片路由規則;第四級目錄用於區分不同的分片;第五級目錄是真正的服務實體,該資訊是動態建立和消失的,同時第五級還提供了一個名稱為 master 的固定檔案,用於主備模式下主機地址的註冊。
服務提供者在釋出服務時,需指定自身的系統名稱、所屬分片(不指定預設分片)、服務地址和埠(不指定則預設)。
如果該服務需要由服務提供者自行決定分片路由的規則,則服務提供者應該在 router 中寫入路由的規則。如果該服務工作在主備模式下,則服務提供者應根據自身策略,在 master 中寫入相應的 IP、PORT 等資訊。
應用可以根據報文中存在的任意一個欄位來定義路由的規則,非常靈活,路由的目的地是系統內的不同分片號。分片號可以根據不同的使用者來劃分,也可以根據不同的業務來劃分(如 A 股 OMS、期權 OMS),還可以根據不同的版本來劃分,這樣系統升級時可以做到部分升級,使用者逐步切換,達到灰度釋出的目的。
2.1.2.2 服務發現
XSTEP 開發包提供統一的服務消費類,使用時需要指定目標系統的名稱,分片的路由方式,具體服務的路由方式(主備或負載均衡)。
開發包會根據應用提供的上述資訊,自動將資料投送到具體的服務提供者,並自動管理服務註冊資訊的變更、鏈路的變化等。 在主備模式下,當主節點發生變化時,開發包會自動建立與新主節點的連線關係。
2.2 閘道器與訂閱服務
完整的通訊框架中,僅有協議開發包是不夠的,因此基於 XSTEP 協議開發包,又實現了統一的閘道器和訂閱中心服務,搭建完整的通訊框架。
為了統一開發模型,我們定義了開發框架和執行時容器 XGATEWAY-PLATFORM,閘道器和訂閱中心作為不同的外掛在該框架中開發,並執行在統一的容器中。
2.2.1 閘道器
閘道器面對的是一個複雜的環境。首先是協議的複雜性:1)接入協議目前使用 XSTEP,後期也有支援 FIX 接入的需求。2)面對的後臺應用有 XSTEP 協議,也有 Dubbo 協議,也有使用 Restful 協議。
其次是部署的複雜性:1)為了交易的穩定可靠,需要區分資訊接入和交易接入。2)需要區分 API 接入和客戶端接入 3)出於安全或合規的考慮,某些接入閘道器上需要遮蔽特定的後臺應用。
閘道器的解決思路是:1)每種協議的接入作為獨立外掛開發 2)使用者登入狀態的管理、流量控制、許可權控制等作為公共基礎服務提供。3)部署時,根據不同的需求,配置不同的外掛和路由規則,形成不同定位的閘道器服務組。4)閘道器在設計上是無狀態的,每個閘道器組內的閘道器可以平行無限擴充套件。5)閘道器內部通過事件驅動的方式投遞事件,通過本地路由規則決定事件最終歸屬的外掛。
下一步閘道器還將對接入的後臺服務進行質量管理,可以做到服務降維,防止部分服務異常導致的系統性風險。
2.2.1.1 登入狀態管理
外部系統訪問閘道器時,必須通過認證的鏈路。一個鏈路通過認證,有兩種方式:1)傳送登入報文,並攜帶合法的使用者標識與口令。2)攜帶此前登入成功時,獲取到的未過期 TOKEN 標識。
登入報文處理邏輯:閘道器通過統一認證校驗標識和口令的合法性,對於驗證合法的登入,閘道器快取統一認證辦法的 TOKEN,將鏈路標識為合法,並將 TOKEN 返回客戶端。由於 TCP 長連線的安全特性,在該鏈路未中斷的情況下,對於鏈路上發起的請求,閘道器不再校驗合法性。但是閘道器會定期通過統一認證校驗此前頒發的 TOKEN 是否失效,如果失效則通知相應鏈路的接入者。
在實際應用中有一種常見的場景,鏈路發生了中斷重連,此時並不希望使用者重新輸入使用者名稱和口令。閘道器在未經認證的鏈路上,此時則會通過快取 TOKEN 進行校驗,自動對鏈路進行合法性認證。
另一種場景是某一臺閘道器服務中斷,或接入者鏈路中斷,重連時接入了一臺新的閘道器。新的閘道器上並沒有快取的 TOKEN 資訊,此時閘道器會向統一認證發起一個 TOKEN 校驗,並獲取該 TOKEN 對應的使用者基本資訊,自動進行鏈路的合法性校驗。
2.2.1.2 流量控制
閘道器支援鏈路級的使用者流量控制。通過 IBOS 執行平臺可以設定每個使用者每秒允許的最大流量及特定功能每秒允許的最大流量。
為了提升流量控制的效率,閘道器並不會統計每條報文的時間,而是基於目標數進行控制。假設使用者的流量限制為 N,則閘道器會在該使用者接入訊息達到 N 時,認為一個統計週期結束,並檢查(結束時間 - 週期開始時間)是否超過一秒。超過限制則觸發流控,該鏈路報文將禁入時間 T。未超過限制,則清空統計報文,開始一個新的統計週期。
2.2.1.3 許可權控制
閘道器為 OMS 等關鍵系統提供了統一的許可權控制服務,使得業務可以專注於業務本身。使用者許可權相關資料儲存於 IBOS 平臺,閘道器會在鏈路鑑權時獲取該資料。
許可權模型定義了交易、訂閱、查詢等許可權,閘道器將每種許可權作為獨立的鑑權例項開發,同時支援通過訊息型別配置訊息所適用的許可權模型,未配置的訊息則不進行許可權控制。
2.2.2 訂閱中心
訂閱中心與閘道器採用相同的框架開發,執行在相同的容器中,只是載入了訂閱中心外掛。訂閱中心支援多種訂閱維度,並支援較為複雜的訂閱條件過濾。
訂閱中心將訂閱關係儲存在 REDIS 中,並通過 KAFAK 接收應用推送的訊息。因此訂閱中心本身是無狀態的,可以水平擴充套件,並且通過 KAFKA 的 PARTITION 機制,可以負載均衡地處理推送訊息。
三、結語
現在讓我們回到初始的幾個問題,並進行回答。
1)客戶端與閘道器間通訊的安全如何保障?如何避免使用者感知鏈路的通斷?
答:XSTEP 支援 TLS 鏈路加密,並提供加密演算法,可對特定欄位加密。通過閘道器的登入狀態管理和 XSTEP 開發包的自動重連機制,可以不感知鏈路的通斷。
2)成交回報如何快速回到客戶端?
答:OMS 接收到成交回報後,推送至訂閱中心,訂閱中心根據使用者的訂閱資訊,主動將成交回報通過閘道器推送至客戶端。無需客戶端主動查詢。
3)我們的業務系統只想關注於業務邏輯,不關注許可權的控制,可以嗎?
答:我們在接入閘道器層實現了通用的許可權控制模型,可以做到訊息級的許可權控制。
4)OMS 是記憶體交易系統,為了解決使用者規模問題,需要基於分片水平擴充套件,高可用方案需要支援分片內的主備機切換,通訊框架可以支援這些需求嗎?
答:XSTEP 的服務釋出機制,支援分片,並且服務提供者可自主控制分片的路由規則。XSTEP 服務釋出支援分片內的主備,並對消費者遮蔽具體的切換邏輯。
5)DownStream 有多個節點,這些節點面向不同的報盤物件,如櫃檯、交易所等,可以對上游的使用者(OMS)遮蔽這些差異嗎?
答:使用分片機制,可以解決上述問題。
6)我們的應用沒有狀態,可以平行擴充套件,所以我們希望消費者可以負載均衡地訪問我們的應用,可以嗎?
答:XSTEP 服務支援分片內的負載均衡的訪問方式,並且對使用者遮蔽細節。
7)可以支援灰度升級嗎?
答:通過分片支援,新的版本部署在新的分片中,並通過使用者屬性配置,逐步將使用者切換到新的服務分片中。
作者介紹:李想,華泰證券資訊科技部系統架構師。關注記憶體交易系統、高效能網路、容器等領域。