N年前曾有一個架構(gòu)設(shè)計的案例捣卤。
一绳锅、需求
【背景】
當(dāng)時集團有10萬名一線員工,每名一線員工工作都手持一個基于Android系統(tǒng)定制的移動設(shè)備(下文簡稱A設(shè)備)蜈膨。類似于手機屿笼,通過SIM卡可進行網(wǎng)絡(luò)通信。其上安裝多個應(yīng)用翁巍,支持多種業(yè)務(wù)驴一。A設(shè)備其中一個附件設(shè)備可支持刷卡支付業(yè)務(wù),簡稱此應(yīng)用為pos應(yīng)用灶壶。另有一個用于無卡支付的應(yīng)用肝断,簡稱為pay應(yīng)用。由于發(fā)展歷程的原因驰凛,兩個應(yīng)用都是符合ISO8583協(xié)議要求胸懈,但對8583部分可自定義的字段由于業(yè)務(wù)場景的不同,有不同的自定義實現(xiàn)恰响。而且這兩個應(yīng)用由不同的開發(fā)團隊實現(xiàn)趣钱,無法兼容。A設(shè)備除了pos應(yīng)用胚宦、pay應(yīng)用還部署了很多集團旗下其它子公司的應(yīng)用首有。pay應(yīng)用、pos應(yīng)用作為前端枢劝,其對應(yīng)的后端應(yīng)用系統(tǒng)也是不同的井联。而根據(jù)業(yè)務(wù)發(fā)展趨勢,后續(xù)的業(yè)務(wù)類型會更多您旁,而自定義的8583報文協(xié)議已經(jīng)顯示出力不從心烙常。特別是從3G網(wǎng)絡(luò)升級到4G網(wǎng)絡(luò),A設(shè)備承載的業(yè)務(wù)將增加圖像等多媒體信息鹤盒。
【需求】
由于集團發(fā)展戰(zhàn)略的需要蚕脏,要進一步加強終端設(shè)備的管控,將只允許A設(shè)備通過https直接接入集團私有云昨悼,再由集團的私有云接到原有機房服務(wù)器蝗锥。如何設(shè)計一個改造方案,能以盡可能低的成本完成集團要求并支持未來發(fā)展需要率触?
原有的部署:pos app / pay app ----( 8583協(xié)議基于tcp短連接 )----> bff ----(hessian rpc ) ----> ms 终议。
要求的部署:A設(shè)備(pos app / pay app) ---- ( https ) ----> 集團的私有云 ---->公司 SF網(wǎng)絡(luò)區(qū)。
【補充】
8583協(xié)議是基于ISO8583報文國際標(biāo)準(zhǔn)的包格式的通訊協(xié)議葱蝗,8583包最多由128個字段域組成穴张,每個域都有統(tǒng)一的規(guī)定,并有定長與變長之分两曼。8583包前面一段為位圖皂甘,它是打包解包確定字段域的關(guān)鍵。8583協(xié)議都是請求響應(yīng)式悼凑,沒有會話狀態(tài)關(guān)聯(lián)多個請求偿枕¤邓玻客戶端發(fā)起一個請求,服務(wù)器端對應(yīng)的接收請求渐夸,驗證請求嗤锉,處理請求,響應(yīng)結(jié)果墓塌。8583報文是二進制數(shù)據(jù)的格式瘟忱。
bff是一個Backend for Frontend前置網(wǎng)關(guān)性質(zhì)的應(yīng)用系統(tǒng),負責(zé)解釋8583報文苫幢,編排串聯(lián)并調(diào)用rpc微服務(wù)访诱,再將rpc微服務(wù)響應(yīng)的結(jié)果,編碼成8583報文響應(yīng)給前端韩肝。前端app 通過8583協(xié)議訪問bff前置系統(tǒng)触菜。而其中的8583協(xié)議是BFF基于mima框架TCP短鏈接實現(xiàn)的,TCP有SSL安全層伞梯。一次請求與響應(yīng)玫氢,就對應(yīng)于一次TCP連接的打開與關(guān)閉帚屉。bff前面有F5負載均衡器谜诫。
ms在這里是指后端的多個微服務(wù)架構(gòu)風(fēng)格的應(yīng)用系統(tǒng),支持hessian 協(xié)議攻旦,micro-service-a, micro-service-b, micro-service-c... 喻旷。bff與ms都部署在公司Server Farms 網(wǎng)絡(luò)區(qū),此網(wǎng)絡(luò)區(qū)與私有云有專線連接牢屋。
二且预、分析
- pay app + pos app 需要支持?jǐn)?shù)千的TPS。
并發(fā)請求不是太高烙无。但A設(shè)備有10萬锋谐,維持10萬的長連接成本較高,是沒有太多必要的截酷。 - 8583報文最大不超過10KB涮拗。
對私有云至SF網(wǎng)絡(luò)區(qū)的專線帶寬有些要求。 - 基本屬于重構(gòu)的范圍迂苛,不涉及業(yè)務(wù)功能的變化三热。但需要支持發(fā)展趨勢。一是一線員工需要假設(shè)一定的增長速度三幻。二是隨著A設(shè)備全部升級為4G網(wǎng)絡(luò)就漾,能承載的業(yè)務(wù)也更多種多樣,8583報文的靈活性不及restful念搬。
- 已自定義的8583報文抑堡,按MESSAGE_TYPE+PROCESSING_CODE計算摆出,包括請求與答復(fù),按1000類報文評估首妖。
如果全部都直接改造系統(tǒng)代碼懊蒸,改為restful風(fēng)格的URL形式,顯然是開發(fā)與測試成本極大的悯搔。想要更低成本的解決方案骑丸,就必須保留8583報文原本的編碼解碼邏輯,將其報文內(nèi)容通過https傳輸妒貌。
三通危、架構(gòu)方案
【設(shè)計思路】
基于以上需求分析,架構(gòu)方案的主要思路是:8583 over http灌曙。
將8583二進制報文內(nèi)容基于https協(xié)議傳輸菊碟。即在HTTP服務(wù)器的配置文件中增加一種自定義的MIME( Multipurpose Internet Mail Extensions)多用途互聯(lián)網(wǎng)郵件擴展類型。例如content-type可命名為"application/pay8583", ”application/pos8583“在刺。只要自已的http服務(wù)器能識別即可逆害。如果http服務(wù)器不方便修改,采用application/octet-stream的content-type也是可行的蚣驼。但需要另外定義一個http頭部字段標(biāo)識具體是哪一種8583自定義報文格式魄幕。
在集團私有云部署3臺Nginx服務(wù)器,使其成下面的訪問鏈路:
A設(shè)備(pos app / pay app) ---- ( 8583 over https ) ----> 私有云Nginx ----(8583 over http)----> bff ----(hessian rpc ) ----> ms 颖杏。
【pos app / pay app 改造】
- 將原本的TCP(SSL)連接改為 https連接纯陨。按下文Nginx要求,增加請求及響應(yīng)時的http首部字段留储。
- 8583報文不需要改動翼抠,以二進制格式通過https傳輸。
【私有云部署Nignx】
Nginx前可利用私有云已有的負載均衡器(例如可能的LVS-DR + Keepalive)获讳。
修改Nginx配置文件 mime.types阴颖。使其支持content-type "application/pay8583",對于自定義的content-type丐膝,只支持post請求方法量愧,不支持GET/PUT/DELETE/HEAD等請求方法。
修改nginx.conf 的http配置塊尤误,修改keepalive_timeout保持與前端一定時長的連接侠畔。
修改nginx.conf 的server配置塊,配置https ssl_certificate损晤。Nginx可以卸載SSL層软棺,轉(zhuǎn)換為普通的http長連接給到BFF。
修改nginx.conf 的location配置塊,proxy_pass尤勋。
根據(jù)context反向代理至對應(yīng)的bff喘落。例如 https://domain-name/pos 轉(zhuǎn)發(fā)至pos-bff茵宪,https://domain-name/pay轉(zhuǎn)發(fā)至pay-bff,https://domain-name/biz-new轉(zhuǎn)發(fā)至新的業(yè)務(wù)瘦棋。不同的context可以對應(yīng)到不同的前端app/ 不同的業(yè)務(wù)類型 / 不同的子公司稀火。biz-new可以采用新的restful風(fēng)格。domain-name/pay的業(yè)務(wù)可以在未來長期的系統(tǒng)功能迭代過程中赌朋,慢慢的逐步的將8583報文轉(zhuǎn)換為restful風(fēng)格凰狞。如果原有業(yè)務(wù)長期沒有變化,則保持為8583格式沛慢。保持與BFF的長連接赡若。
proxy_http_version 1.1;
proxy_set_header Connection "";
keepalive 16;
- 轉(zhuǎn)發(fā)客戶端真實IP
proxy_set_header X-Real-IP $remote_addr;
請求時,Nginx應(yīng)該轉(zhuǎn)發(fā)這些首部字段: Host团甲, Accept逾冬, User-Agent, Connection躺苦, Keep-Alive身腻, Content-Type, Content-Length匹厘。
響應(yīng)時嘀趟,Nginx應(yīng)該轉(zhuǎn)發(fā)這些首部字段:Connection, Keep-Alive集乔, Cache-Control去件,Content-Type坡椒, Content-Length扰路。
【BFF改造】
需要增加一個DispatcherServlet,用于從http post的request body獲得8583報文倔叼,轉(zhuǎn)交給BFF原有的解碼器汗唱。
增加一個Header8583Filter,用于檢查下面 8583 over https 設(shè)計中所要求的 HTTP 首部字段丈攒, 不合法時返回 400 狀態(tài)碼哩罪, 合法時設(shè)置響應(yīng)首部。
Accept應(yīng)該為”application/pay8583“巡验,User-Agent應(yīng)該為”<device_name>-<app_name>-version“际插,Content-Type應(yīng)該為”application/pay8583“,Cache-Control應(yīng)該為” no-cache“显设。
當(dāng)BFF編排微服務(wù)框弛, 發(fā)生了 Hessian 超時或其它意外異常時, 應(yīng)當(dāng)響應(yīng)500狀態(tài)碼捕捂。 嚴(yán)禁將服務(wù)器異常堆棧信息返回終端設(shè)備瑟枫。待上線驗證沒問題后斗搞,逐步移除mina 框架。 改造后的方案不再使用 mina 框架慷妙, 而是利用了 Servlet 容器對于 Http 協(xié)議的支持僻焚。并且原本的大量的 TCP 短連接,已有私有云服務(wù)器 nginx 承接膝擂,轉(zhuǎn)變?yōu)樯倭康?http 長連接虑啤。
禁用Cookie,BFF不需要HttpSession架馋。
8583報文不需要改動咐旧,后續(xù)ms都不需要有任何改動。最大限度的減少開發(fā)的工程量绩蜻。