前言
開放平臺設(shè)計系列第一篇主要寫了開放平臺功能方面的設(shè)計,原計劃寫3篇,一篇介紹功能,一篇介紹架構(gòu),一篇介紹使用的技術(shù)。寫了第一篇功能后,發(fā)現(xiàn)架構(gòu)和技術(shù)可以合并寫,這樣看起來更方便些,所以本篇就把架構(gòu)和技術(shù)合并了。合并起來還有一方面是因為涉及到公司實施細(xì)節(jié)不能把架構(gòu)的細(xì)節(jié)寫出來,只能簡化的描述下架構(gòu),這樣架構(gòu)的概述就太少了沒辦法撐起一篇文章,在后面技術(shù)實現(xiàn)會講解下各個功能模塊的實現(xiàn)方式。
1. 總架構(gòu)概述
下面直接上架構(gòu)圖來描述下通用版開放平臺的架構(gòu),這里已經(jīng)刪掉了所有涉及到公司隱私的信息。架構(gòu)上總體上分為以下幾部分:
互聯(lián)網(wǎng)接入web server(web server):負(fù)責(zé)互聯(lián)網(wǎng)外部請求的接入,webserver一般使用nginx負(fù)責(zé)負(fù)載和反代,一般都是將webserver部署在兩層防火墻包圍的DMZ區(qū)用來內(nèi)外網(wǎng)的安全隔離;
開放平臺接入網(wǎng)關(guān)(openapi gateway):負(fù)責(zé)接收互聯(lián)網(wǎng)接入轉(zhuǎn)發(fā)的交易請求,網(wǎng)關(guān)是線型集群部署在內(nèi)網(wǎng),負(fù)責(zé)請求的限流、熔斷、計費等功能;
開放平臺門戶(openapi portal):門戶主要負(fù)責(zé)提供給開發(fā)者使用的門戶頁面和服務(wù)申請、應(yīng)用管理等功能。門戶也是采用了集群部署的應(yīng)用服務(wù);
開放平臺內(nèi)管(openapi management):內(nèi)管主要提供給管理員進(jìn)行內(nèi)部服務(wù)、應(yīng)用審核、基本維護(hù)使用,也是集群部署的應(yīng)用服務(wù);
服務(wù)注冊發(fā)現(xiàn)中心(service center):服務(wù)注冊中心是整個服務(wù)化的核心,這里服務(wù)發(fā)現(xiàn)中心主要實現(xiàn)了服務(wù)路由和內(nèi)部服務(wù)注冊、發(fā)現(xiàn)的功能,這里也是采用了集群部署;
安全服務(wù):安全服務(wù)因為是基礎(chǔ)服務(wù),所以將所有服務(wù)都注冊到了service center供所有系統(tǒng)使用;
oauth服務(wù):oauth因為也屬于開放平臺基礎(chǔ)服務(wù),所以這里將oauth所有服務(wù)都注冊到了service center;
開放平臺服務(wù)組合(BIM):服務(wù)組合對原子基礎(chǔ)服務(wù)進(jìn)行組合后再發(fā)布到service center,也是一個比較核心的模塊,有的公司將服務(wù)組合從開放平臺中剝離出來單獨作為一個服務(wù)組合系統(tǒng)。BIM也是采取了線性集群部署的方式。
開放平臺內(nèi)部服務(wù)管理(openapi server):內(nèi)部服務(wù)管理主要實現(xiàn)了所有開放平臺服務(wù)元數(shù)據(jù)的管理、服務(wù)接口的配置、應(yīng)用元數(shù)據(jù)管理等。

2. 服務(wù)接入網(wǎng)關(guān)
服務(wù)網(wǎng)關(guān)的實現(xiàn)比較簡單,主要有幾個關(guān)鍵點,下面介紹下:
- 外部服務(wù)接入:服務(wù)接入功能其實比較簡單,一般都是使用Spring MVC或者SpringBoot直接定義Controller來實現(xiàn)服務(wù)接入,但是這樣會導(dǎo)致,如果有多少服務(wù)對外開放就要定義多少個Controller,如果使用springcloud的話可以使用類似zuul這樣的透傳網(wǎng)關(guān)來實現(xiàn),當(dāng)然也可以自己實現(xiàn)一個通用的接入controller,然后根據(jù)請求uri來實現(xiàn)其他的接入路由、限流等功能。
- 服務(wù)限流、熔斷:作為一個開放平臺的接入網(wǎng)關(guān),還需要有限流和熔斷的功能,目前比較成熟的方案就是Hystrix,通過Hystrix可以很方便的實現(xiàn)服務(wù)限流和熔斷,具體實現(xiàn)可以參考我之前寫的關(guān)于Hystrix的文章。當(dāng)然如果不使用Hystrix的話,也可以自己實現(xiàn),限流主要分兩個緯度一個是并發(fā)限流,一個是指定時間內(nèi)總調(diào)用次數(shù)限流,實現(xiàn)并發(fā)限流可以通過線程池方案,對于每個商戶每個服務(wù)創(chuàng)建一個線程池,通過線程池機制來實現(xiàn)并發(fā)控制,看過Hystrix源碼的同學(xué)應(yīng)該知道Hystrix實現(xiàn)并發(fā)限流也是通過線程池方案進(jìn)行隔離。對于并發(fā)限流還可以通過Token池方案進(jìn)行控制,其實原理和線程池類似,但是token池方案更加輕量級,為每個商戶每個服務(wù)創(chuàng)建一個token池,如果有服務(wù)請求則從token池中拿一個token占用,服務(wù)調(diào)用完成后歸還token,如果所有token被占用則不能再調(diào)用服務(wù)。實現(xiàn)了限流實現(xiàn)熔斷其實就比較簡單了,當(dāng)判斷出來觸發(fā)服務(wù)熔斷后會自動進(jìn)行降級處理,如果接口定義了降級策略則固定返回降級報文即可。
- 服務(wù)計費:服務(wù)計費其實是基于服務(wù)次數(shù)限流實現(xiàn)的,通過對服務(wù)次數(shù)的統(tǒng)計實現(xiàn)即可,服務(wù)次數(shù)統(tǒng)計為了保證性能一般都是通過內(nèi)存計數(shù)或者redis計數(shù),用內(nèi)存計數(shù)存在一個問題就是如何保證HA,所以推薦使用redis集群來進(jìn)行服務(wù)計數(shù);
- 服務(wù)分布式擴(kuò)展:服務(wù)接入網(wǎng)關(guān)的壓力是非常大的,所以要支持分布式線性擴(kuò)展,要實現(xiàn)線性擴(kuò)展就要求所有的交易都是無狀態(tài)的短連接,使用訪問令牌的方式來保證登陸有效性檢查;
3. 服務(wù)組合
服務(wù)組合是開放平臺中比較常見的功能模塊,服務(wù)組合一般有兩類,服務(wù)接口順序、并行組合,自定義邏輯接口組合。
- 順序接口組合:這里說的順序接口組合其實指的是狹義的順序接口組合就是先調(diào)用接口1然后將接口1的返回報文中的部分字段作為接口2的請求字段,再繼續(xù)調(diào)用接口2以此類推,順序接口組合在實際使用中其實遇到的不多,大部分的接口組合要么是并發(fā)調(diào)用結(jié)果聚合返回,要么是存在很多自定義邏輯,需要對每個接口的返回報文加工后再調(diào)用下一個接口的場景。順序接口組合實現(xiàn)起來其實也比較簡單,其實就是在接口配置表中配置好接口依賴關(guān)系和輸入輸出字段對應(yīng),在收到組合接口請求后由一個線程根據(jù)接口配置表的元數(shù)據(jù)串型依次調(diào)用接口;
- 并行接口組合:并行接口組合其實使用場景比較多,尤其是在移動端場景,經(jīng)常在移動端的頁面存在多個重復(fù)的接口調(diào)用,這時服務(wù)組合其實可以進(jìn)行并行組合后將結(jié)果聚合返回,這樣就可以避免前端多次發(fā)起網(wǎng)絡(luò)連接請求數(shù)據(jù),前端只需要發(fā)送一次請求,由服務(wù)組合模塊根據(jù)請求并發(fā)發(fā)起服務(wù)調(diào)用,服務(wù)端調(diào)用都是內(nèi)網(wǎng)調(diào)用速度比無線調(diào)用要快好幾個數(shù)量級,服務(wù)端并發(fā)調(diào)用有結(jié)果返回后再將結(jié)果進(jìn)行聚合返回給前端。這里并行接口調(diào)用可以使用java.concurrent庫中的fork/join來實現(xiàn),但是要注意處理并發(fā)組合接口某個接口調(diào)用異常的處理;
- 自定義邏輯接口組合:自定義邏輯接口組合目前主流的有兩種方式,一種是純編碼實現(xiàn)所有的組合邏輯,還有一種是定義一個服務(wù)組合接口,開發(fā)者只需要實現(xiàn)接口并實現(xiàn)代碼片段就可以了,這其實和目前流行的serverless一樣。
4. oauth
oauth是開放平臺一個不可或缺模塊,oauth具體有什么功能這里我就不介紹了,可以參考之前轉(zhuǎn)發(fā)的一篇關(guān)于oauth的文章,這里主要說下oauth的實現(xiàn)方式,如果是實現(xiàn)標(biāo)準(zhǔn)的oauth的3種模式,可以基于spring security和Apache的Shrio這兩套框架來實現(xiàn),但是目前我了解下來還是有很多公司實現(xiàn)的oauth協(xié)議其實加了很多自己的定制化需求,如果有很多定制化需求的建議還是自己實現(xiàn)一套,實現(xiàn)難度其實不大,主要就是實現(xiàn)token發(fā)放、token校驗、token有效期處理、token更換等基礎(chǔ)功能,純自研的話功能肯定沒有用框架那么豐富,但是所有代碼可控自主性更高。
5. 服務(wù)注冊管理
服務(wù)注冊管理的實現(xiàn)其實沒什么好說的,用的技術(shù)其實就是傳統(tǒng)的java web,服務(wù)注冊管理其實就是對開放平臺所有的應(yīng)用、服務(wù)、接口配置等元數(shù)據(jù)進(jìn)行統(tǒng)一管理的模塊,只要需求功能清晰,按需求實現(xiàn)就可以了。
6. 服務(wù)注冊發(fā)現(xiàn)中心
服務(wù)注冊發(fā)現(xiàn)中心不是簡單的服務(wù)路由分發(fā)、服務(wù)注冊、服務(wù)發(fā)現(xiàn),其實還涉及到服務(wù)的可用性管理、服務(wù)監(jiān)控等等內(nèi)容,這里推薦使用現(xiàn)成的,不要重復(fù)造輪子,可以使用zookeeper或者eureka,筆者之前所在的項目分別使用過dubbo+zk的組合和springboot+eureka的組合,兩種各有優(yōu)缺點,這里更加推薦使用后者,目前springcloud有一統(tǒng)微服務(wù)江湖的趨勢,而且更新越來越快,雖然阿里又對dubbo重新進(jìn)行維護(hù),但是擔(dān)心阿里開源的尿性,小東西用用沒問題,像服務(wù)治理框架這樣的還是算了,萬一出問題想死的心都有了。
7. 安全
上一篇文章里說過開放平臺的核心其實不是開放接口而是如何保證安全,開放平臺的安全其實涉及到以下幾方面需要考慮的地方:
- 服務(wù)報文加解密:服務(wù)報文加解密主要思路就是秘鑰通過非對稱加密來保證安全,業(yè)務(wù)報文或者關(guān)鍵字段使用對稱加密來保證安全,還可以通過白盒加密等技術(shù)來加強安全,因為安全這塊內(nèi)容涉及到很多方案和實現(xiàn)方式,后續(xù)單獨寫一篇關(guān)于加解密的文章,詳細(xì)說說里面的東東;
- 交易簽名:通過交易簽名來防交易被篡改,交易簽名一般使用非對稱加密+散列算法來實現(xiàn);
- 應(yīng)用秘鑰管理:對于使用到的對稱秘鑰或者非對稱公私鑰都要進(jìn)行管理,如果已經(jīng)有了CA系統(tǒng),可以直接復(fù)用CA中心的秘鑰管理,也可以自建密鑰管理,自建一般安全性方面會存在很多安全問題,但是可以實現(xiàn)基本功能;
- 應(yīng)用接口權(quán)限控制:對于每個開發(fā)者調(diào)用接口的權(quán)限控制,其實就是一個1對N的關(guān)系映射,實現(xiàn)方面沒有什么可說的;
- oauth令牌機制:上文已經(jīng)說了;
- 黑白名單:黑白名單也是安全防護(hù)的基礎(chǔ)功能,其實核心就是在交易調(diào)用的時候進(jìn)行黑白名單的判斷,這里要保證的就是性能問題,可以通過將黑白名單保存在內(nèi)存或者redis中來緩存保證讀取性能;
- 字段脫敏還原:對于一些敏感字段需要進(jìn)行脫敏后返回給前端,脫敏簡單,難的是還原,對于內(nèi)部系統(tǒng)存儲的數(shù)據(jù)一定是還原后的數(shù)據(jù),所以只有在請求進(jìn)來的時候要對報文解密后對脫敏字段進(jìn)行還原后再進(jìn)行持久化或者發(fā)給源系統(tǒng);
- 交易反欺詐:以前做的開放平臺一般都沒有反欺詐模塊,最近兩年大數(shù)據(jù)火了以后,基于大數(shù)據(jù)的交易反欺詐也火了起來,很多開放平臺也做起了交易反欺詐,交易反欺詐目前大部分都是事后黑名單機制,每筆交易關(guān)鍵要素都會送反欺詐系統(tǒng),反欺詐系統(tǒng)會通過storm這類實時計算出可疑交易名單,并將名單和黑名單聯(lián)動,后續(xù)再有黑名單中交易發(fā)起時就會觸發(fā)反欺詐動態(tài)安全策略。
8. 沙箱
沙箱主要實現(xiàn)的功能就是服務(wù)模擬,沙箱實現(xiàn)要注意以下幾點:
- 報文模擬:報文模擬可以使用類似MockServer這樣的報文模擬工具,其實有很多類似的報文模擬工具,甚至可以自己實現(xiàn)一個簡單的報文模擬工具;
- 測試數(shù)據(jù)初始化:對于一些智能沙箱,需要對測試數(shù)據(jù)進(jìn)行初始化,初始化后可以進(jìn)行重新的測試,這樣可以保證臟數(shù)據(jù)的及時清理;
- 測試帳號管理:對于使用沙箱的開發(fā)者也需要有一個測試帳號的管理功能,可以方便開發(fā)者自己創(chuàng)建一些測試帳號;
- docker:如果使用了docker的公司可以考慮使用docker來實現(xiàn)測試環(huán)境數(shù)據(jù)的清理,目前我也在測試使用容器化技術(shù)來快速創(chuàng)建測試環(huán)境。
9. 門戶、內(nèi)管
門戶和內(nèi)管其實沒什么好說的其實都是一些portal,只是針對的用戶不一樣,實現(xiàn)的技術(shù)也就是傳統(tǒng)的java web技術(shù),如果前端要顯示的酷炫一些就使用一些H5的技術(shù)。因為在門戶和內(nèi)管中還會涉及到一些監(jiān)控的功能,監(jiān)控模塊這里就不單獨弄一節(jié)描述了,其實監(jiān)控可以借助于一些三方組件來實現(xiàn),目前主流的實現(xiàn)方案主要是將各個系統(tǒng)的服務(wù)接口調(diào)用都推送到一個監(jiān)控平臺,由監(jiān)控平臺根據(jù)推送過來的數(shù)據(jù)進(jìn)行實時數(shù)據(jù)展示。
總結(jié)
本文對于開放平臺一些核心內(nèi)容如何實現(xiàn)做了簡要介紹,每部分其實都可以單寫一篇文章,開放平臺中其實涉及到的技術(shù)還是很多的,希望大家慢慢體會。