閆鍇明,白 麗,林德輝,肖華平,宗慧曦
(1. 中國(guó)鐵道科學(xué)研究院集團(tuán)有限公司 電子計(jì)算技術(shù)研究所,北京 100081;2. 廣州地鐵集團(tuán)有限公司,廣州 510380)
城市軌道交通信息化橫跨多個(gè)專業(yè),線網(wǎng)環(huán)境下眾多信息系統(tǒng)之間相互依賴,逐漸形成網(wǎng)狀調(diào)用關(guān)系,不便于管理和維護(hù)[1]。作為一種分布式云架構(gòu)的服務(wù)調(diào)用模式,云服務(wù)網(wǎng)關(guān)可將不同系統(tǒng)的調(diào)用集中到一個(gè)可彈性擴(kuò)展的公共平臺(tái)中,支持系統(tǒng)間資源調(diào)度、數(shù)據(jù)交互和業(yè)務(wù)連接,形成統(tǒng)一的資源與業(yè)務(wù)共享平臺(tái),并提供統(tǒng)一的身份認(rèn)證、操作鑒權(quán)、流量管控、超時(shí)熔斷、監(jiān)控告警等功能,有助于提高信息系統(tǒng)的穩(wěn)定性,促進(jìn)信息系統(tǒng)開(kāi)發(fā)、運(yùn)行和集成效率的提升[2]。
針對(duì)城市軌道交通信息系統(tǒng)綜合集成的發(fā)展需求,參考國(guó)內(nèi)外各類開(kāi)源軟件系統(tǒng)[3],對(duì)云服務(wù)網(wǎng)關(guān)進(jìn)行應(yīng)用研究。
云服務(wù)網(wǎng)關(guān)具備云原生屬性,可單獨(dú)組建集群運(yùn)行,也可運(yùn)行Kubernetes 集群來(lái)解決微服務(wù)內(nèi)部IP 暴露的問(wèn)題,適用于微服務(wù)和傳統(tǒng)架構(gòu)并存的環(huán)境[4]。云服務(wù)網(wǎng)關(guān)可封裝系統(tǒng)內(nèi)部結(jié)構(gòu),實(shí)現(xiàn)以1 個(gè)API 網(wǎng)關(guān)接管所有入口流量的服務(wù),在網(wǎng)關(guān)層處理所有的非業(yè)務(wù)事務(wù)[5]。
參考國(guó)內(nèi)外主流開(kāi)源軟件和應(yīng)用案例,綜合考慮用戶活躍度、易用性、擴(kuò)展性,選取開(kāi)源軟件系統(tǒng)Nginx+Openresty+Kong[6]進(jìn)行分析研究和應(yīng)用實(shí)踐。
Nginx 是由俄羅斯團(tuán)隊(duì)開(kāi)發(fā)的基于C 語(yǔ)言的高性能Web 負(fù)載均衡開(kāi)源軟件,部署簡(jiǎn)單,適用于高并發(fā)業(yè)務(wù)場(chǎng)景,如12306 互聯(lián)網(wǎng)售票系統(tǒng)等[7]。
OpenResty 是中國(guó)團(tuán)隊(duì)開(kāi)發(fā)的基于Ngnix 和Lua的高性能開(kāi)源Web 平臺(tái),支持C 語(yǔ)言,內(nèi)部打包和集成Lua 庫(kù)、第三方模塊及其依賴項(xiàng)。OpenResty 運(yùn)行在Ngnix 上,支持非阻塞I/O 和后端分布式數(shù)據(jù)庫(kù)、分布式緩存,能夠?qū)崿F(xiàn)一致的高性能響應(yīng);除了繼承Nginx 的高并發(fā)等特點(diǎn),OpenResty 還增強(qiáng)了擴(kuò)展性和動(dòng)態(tài)網(wǎng)關(guān)服務(wù)能力,在互聯(lián)網(wǎng)行業(yè)也得到廣泛應(yīng)用[8]。
Kong 是1 個(gè)OpenResty 應(yīng)用,用于管理API。目前,Kong 的插件眾多,具有工具化和模塊化的發(fā)展特點(diǎn),其易用性和可視化管理界面有助于降低企業(yè)級(jí)應(yīng)用和擴(kuò)展性開(kāi)發(fā)的難度[9]。Kong 支持容器化部署,提供Docker 鏡像,可運(yùn)行于容器之中,也可以運(yùn)行于虛擬機(jī)和物理服務(wù)器集群環(huán)境。在Kubernetes 中,Kong 以Pod 節(jié)點(diǎn)形式運(yùn)行,所有Kong 節(jié)點(diǎn)共享1 個(gè)數(shù)據(jù)庫(kù)作為注冊(cè)中心;在容器的微服務(wù)架構(gòu)中,Kong 作為集群的統(tǒng)一入口,通過(guò)節(jié)點(diǎn)端口映射接入外部流量,集群內(nèi)的服務(wù)間通信通過(guò)服務(wù)命名調(diào)用[10]。如圖1 所示,按推薦的部署方式,將Kong 管理功能獨(dú)立部署為1 個(gè)Pod,僅提供配置管理功能,其它Kong 容器集群節(jié)點(diǎn)專門提供流量轉(zhuǎn)發(fā)功能。此外,Kong 提供Kubernetes Ingress Controller模塊,可實(shí)現(xiàn)與Kubernetes Ingress 的配置轉(zhuǎn)換。
圖1 Nginx+OpenResty+Kong 云服務(wù)網(wǎng)關(guān)容器部署
Nginx+OpenResty+Kong 云服務(wù)網(wǎng)關(guān)在訪問(wèn)請(qǐng)求到達(dá)后端服務(wù)之前,通過(guò)Lua 插件攔截訪問(wèn)請(qǐng)求并進(jìn)行處理。如圖2 所示,云服務(wù)網(wǎng)關(guān)分5 個(gè)層次來(lái)過(guò)濾、轉(zhuǎn)發(fā)和處理業(yè)務(wù)訪問(wèn)請(qǐng)求。
圖2 云服務(wù)網(wǎng)關(guān)的分層結(jié)構(gòu)
轉(zhuǎn)發(fā)層:由Nginx 服務(wù)器接收API 請(qǐng)求,根據(jù)負(fù)載均衡配置,將請(qǐng)求均勻地分發(fā)至各個(gè)Server,以及時(shí)響應(yīng)大批量的網(wǎng)絡(luò)訪問(wèn)。
引擎層:網(wǎng)關(guān)引擎OpenResty 對(duì)客戶端請(qǐng)求和后端數(shù)據(jù)層進(jìn)行一致的高性能響應(yīng),實(shí)現(xiàn)請(qǐng)求/響應(yīng)及Lua 處理。
集群與數(shù)據(jù)存儲(chǔ)層:集群是指各個(gè)節(jié)點(diǎn)使用一致性協(xié)議自動(dòng)發(fā)現(xiàn)其它節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)均緩存全局信息,當(dāng)某個(gè)節(jié)點(diǎn)的配置變更時(shí),會(huì)通過(guò)隨機(jī)傳播機(jī)制,將變更泛洪給網(wǎng)絡(luò)上的全部節(jié)點(diǎn);API 注冊(cè)和管理基于數(shù)據(jù)庫(kù),存儲(chǔ)集群節(jié)點(diǎn)、API、消費(fèi)者、插件等信息。在高訪問(wèn)量的應(yīng)用場(chǎng)景下,可部署PostgreSQL、MySQL、Cassandra 等分布式集群來(lái)支持負(fù)載均衡和高可用,同時(shí)還支持Redis 緩存數(shù)據(jù)庫(kù)集群橫向擴(kuò)展[11]。
插件層:使用Lua 腳本語(yǔ)言調(diào)用Nginx 轉(zhuǎn)發(fā);Lua 體積小、啟動(dòng)速度快、嵌入性好、接口易擴(kuò)展,在工控領(lǐng)域常用作Modbus 數(shù)據(jù)轉(zhuǎn)換。Kong 社區(qū)提供豐富的Lua 插件模板,可提供權(quán)限認(rèn)證、熔斷、流量控制等擴(kuò)展服務(wù),使用時(shí)可直接導(dǎo)入加載。
API 管理層:基于Kong 開(kāi)源框架,實(shí)現(xiàn)API 從注冊(cè)到注銷的全生命周期管理,Kong 社區(qū)提供2 種可視化管理平臺(tái):Konga 和Kong-Dashboard,可使用REST 命令或控制臺(tái)注入和發(fā)布網(wǎng)關(guān)的配置策略。
如圖3 所示,Nginx+OpenResty+Kong 云服務(wù)網(wǎng)關(guān)的核心功能包括統(tǒng)一接入、權(quán)限認(rèn)證、流量管理、安全防護(hù)、監(jiān)控日志等模塊。
云服務(wù)網(wǎng)關(guān)負(fù)責(zé)統(tǒng)一接入,將請(qǐng)求的協(xié)議轉(zhuǎn)換成內(nèi)部的接口協(xié)議,調(diào)用過(guò)程中可采用限流、降級(jí)、熔斷、容錯(cuò)等方式來(lái)保護(hù)網(wǎng)關(guān)運(yùn)行穩(wěn)定;網(wǎng)關(guān)具備訪問(wèn)控制、黑白名單等基本安全措施,當(dāng)作為開(kāi)放網(wǎng)關(guān)使用時(shí),還可嵌入身份認(rèn)證功能;引入Lua 插件模板,還可將一些基本的校驗(yàn)判斷邏輯前置于應(yīng)用系統(tǒng),便于輕量化地處理接入問(wèn)題。
(1)負(fù)載均衡接入
轉(zhuǎn)發(fā)層Nginx 實(shí)例可以集群方式部署,支持基于策略配置的自動(dòng)擴(kuò)容,支持高并發(fā)連接,通過(guò)重定向或權(quán)重策略來(lái)實(shí)現(xiàn)流量負(fù)載相對(duì)均衡;API 的更改可動(dòng)態(tài)生效,無(wú)需重新加載或重新啟動(dòng)。
(2)服務(wù)路由
服務(wù)路由是REST(表述性狀態(tài)傳遞)訪問(wèn)路徑以及客戶端請(qǐng)求的具體匹配規(guī)則;每個(gè)路由都與1個(gè)服務(wù)相關(guān)聯(lián),而每個(gè)服務(wù)可能有多個(gè)與之相關(guān)聯(lián)的路由。每1 個(gè)與給定路徑匹配的請(qǐng)求都將被提交給與之相關(guān)聯(lián)的服務(wù),可在服務(wù)路由中定義細(xì)粒度的路由與服務(wù)組合的入口點(diǎn),將請(qǐng)求訪問(wèn)引導(dǎo)至不同的目標(biāo)IP 池和端口,實(shí)現(xiàn)路徑控制和負(fù)載均衡。
(3)服務(wù)注冊(cè)
通過(guò)集群和數(shù)據(jù)庫(kù)層,可將部署服務(wù)的主機(jī)地址記錄在注冊(cè)中心,服務(wù)消費(fèi)者查詢注冊(cè)中心可獲得所訪問(wèn)服務(wù)的地址,以發(fā)起調(diào)用和監(jiān)聽(tīng)服務(wù)狀態(tài)。
(4)藍(lán)綠發(fā)布
藍(lán)綠發(fā)布是一種常用新舊程序切換策略,目的是盡可能避免因發(fā)布升級(jí)程序?qū)е碌姆?wù)不可用問(wèn)題。如圖4 所示,使用upstream(后端轉(zhuǎn)發(fā)策略映射)為服務(wù)編排藍(lán)綠部署,通過(guò)設(shè)置藍(lán)綠環(huán)境的轉(zhuǎn)發(fā)權(quán)重來(lái)實(shí)現(xiàn)DNS 倒換,藍(lán)/綠開(kāi)關(guān)激活可動(dòng)態(tài)更新,若需回退升級(jí)程序,恢復(fù)配置即可生效。
(5)訪問(wèn)控制
圖3 Nginx+OpenResty+Kong 云服務(wù)網(wǎng)關(guān)功能框架
圖4 藍(lán)綠發(fā)布示意
在認(rèn)證機(jī)制的基礎(chǔ)上,建立為用戶分配API 授權(quán)的ACL(訪問(wèn)控制列表)策略組,服務(wù)與權(quán)限是一對(duì)一關(guān)系,每1 個(gè)服務(wù)或API 具有唯一的權(quán)限,通過(guò)設(shè)置用戶的權(quán)限,限制用戶只能訪問(wèn)指定的API。
(6)身份認(rèn)證
采用令牌、簽名與API 網(wǎng)關(guān)結(jié)合的方式實(shí)現(xiàn)用戶身份驗(yàn)證;在用戶授權(quán)的情況下,通過(guò)服務(wù)認(rèn)證,在資源服務(wù)器上安全地獲得對(duì)應(yīng)的用戶資源;插件提 供Basic-Auth、Key-auth、OAuth2.0、HMAC-auth、JWT、LDAP-auth 等多種認(rèn)證方式。
(7)IP 黑白名單
Kong 提供IP 黑白名單控制插件,可從2 個(gè)維度進(jìn)行配置—針對(duì)所有API 接口或特定API 接口,針對(duì)所有消費(fèi)方或特定消費(fèi)方;IP 可以設(shè)置為1 個(gè)區(qū)段,也可設(shè)置為特定IP 地址。
(8)流量控制
限流可用于防止惡意攻擊行為。結(jié)合路由,插件基于自定義響應(yīng)消息頭進(jìn)行速率限制,可設(shè)置秒/分鐘/小時(shí)不同粒度的請(qǐng)求次數(shù);同時(shí),插件提供數(shù)據(jù)庫(kù)、Redis 緩存和本地緩存3 種方式記錄請(qǐng)求頻率,大規(guī)模集群環(huán)境下建議使用Redis 緩存。
熔斷通過(guò)插件定義指定請(qǐng)求或拒絕上層服務(wù),直接返回指定的內(nèi)容進(jìn)行熔斷,多應(yīng)用于業(yè)務(wù)系統(tǒng)版本升級(jí)的場(chǎng)景,可對(duì)正在升級(jí)的業(yè)務(wù)系統(tǒng)的所有服務(wù)進(jìn)行熔斷;啟用熔斷策略,應(yīng)根據(jù)應(yīng)用系統(tǒng)的業(yè)務(wù)特點(diǎn),充分評(píng)估和謹(jǐn)慎使用。
(9)監(jiān)控與日志采集
基于數(shù)據(jù)采集的開(kāi)源監(jiān)控插件,支持多種數(shù)據(jù)采集方式,具有Zipkin 分布式跟蹤能力,可用于監(jiān)控系統(tǒng)中數(shù)據(jù)接口時(shí)間消耗問(wèn)題,提供數(shù)據(jù)收集和查詢等功能,可與Grafana 集成,實(shí)現(xiàn)數(shù)據(jù)可視化展示。
使用2 臺(tái)虛擬機(jī)搭建實(shí)驗(yàn)室測(cè)試環(huán)境,部署網(wǎng)關(guān)服務(wù)組件,編寫(xiě)運(yùn)行Spring boot 測(cè)試用例,模擬負(fù)載均衡、流量控制、安全驗(yàn)證、黑白名單、監(jiān)控日志等功能。
以虛擬機(jī)方式部署2 臺(tái)Centos7.8 服務(wù)器,其中,192.168.9.135 作為網(wǎng)關(guān)服務(wù)器,以Docker 方式構(gòu)建3 個(gè)鏡像,分別運(yùn)行云服務(wù)網(wǎng)關(guān)Server、PostgreSQL數(shù)據(jù)庫(kù)和Konga 管理控制臺(tái);另一臺(tái)192.168.9.136作為Web 服務(wù)器,用Spring Boot 打包運(yùn)行Web 測(cè)試用例,運(yùn)行端口為9080 和9081。
在客戶端和網(wǎng)關(guān)服務(wù)器的本地hosts 文件中配置“192.168.9.135 test.ykm.com”域名映射,以模擬DNS 轉(zhuǎn)發(fā);客戶端瀏覽器發(fā)起訪問(wèn)路徑,以域名test.ykm.com 請(qǐng)求連接到網(wǎng)關(guān)服務(wù)器,由網(wǎng)關(guān)服務(wù)器轉(zhuǎn)發(fā)至Web 服務(wù)器的9080 和9081 端口,通過(guò)網(wǎng)關(guān)策略進(jìn)行多項(xiàng)功能測(cè)試,如圖5 所示。
圖5 測(cè)試環(huán)境部署
(1)負(fù)載均衡測(cè)試與URL 轉(zhuǎn)換測(cè)試
在客戶端hosts 中增加指向服務(wù)網(wǎng)關(guān)服務(wù)器的設(shè)置,即“192.168.9.135 test.ykm.com”,瀏覽器通過(guò)IP 地址“192.168.9.136”訪問(wèn)Web 服務(wù)器時(shí),訪問(wèn)請(qǐng)求會(huì)被輪流分發(fā)到9081 或9080 端口,如圖6 所示。
圖6 負(fù)載均衡測(cè)試
在配置文件中設(shè)置URL 替換策略,將所有模糊匹配“test.ykm.com”的域名訪問(wèn)默認(rèn)指向虛擬目錄“test.ykm.com/yankaiming/get”。
(2)IP 白名單測(cè)試
在服務(wù)路由中添加設(shè)置IP 只允許192.168.9.135訪問(wèn),客戶端IP 地址設(shè)置為192.168.9.10,瀏覽器提示IP 拒絕訪問(wèn)。
(3)流量控制測(cè)試
在服務(wù)路由中添加設(shè)置每分鐘5 次請(qǐng)求訪問(wèn),超過(guò)5 次后客戶端瀏覽器訪問(wèn)服務(wù)時(shí)會(huì)提示訪問(wèn)超限。
(4)權(quán)限認(rèn)證及訪問(wèn)控制測(cè)試
在服務(wù)路由中添加設(shè)置訪問(wèn)控制插件,設(shè)置策略組和Basic-Auth 用戶名/密碼驗(yàn)證方式,當(dāng)通過(guò)瀏覽器訪問(wèn)時(shí),會(huì)彈出登錄信息對(duì)話框,須驗(yàn)證通過(guò)后才能訪問(wèn)服務(wù)。
(5)日志監(jiān)控及管理控制臺(tái)測(cè)試
使用Prometheus 開(kāi)源監(jiān)控插件捕捉訪問(wèn)請(qǐng)求的返回值次數(shù)、處理延遲時(shí)間等日志數(shù)據(jù);Konga 控制臺(tái)頁(yè)面可顯示基本信息。
(6)插件庫(kù)功能分析
Kong 基于Lua 的開(kāi)源插件庫(kù)提供權(quán)限認(rèn)證、安全管理、流量控制、分析監(jiān)控、日志系統(tǒng)和URL 轉(zhuǎn)換等30 多個(gè)模板,涵蓋API 全生命周期,可通過(guò)圖形化用戶界面來(lái)操作和管理,如圖7 所示。
圖7 Lua 開(kāi)源插件庫(kù)的圖形化用戶界面
測(cè)試過(guò)程中主要對(duì)身份認(rèn)證(Basic auth)、訪問(wèn)控 制(ACL)、IP 限 制(IP restriction)、速 率 限 制(rate limiting)、訪問(wèn)請(qǐng)求轉(zhuǎn)換(request transformer)、日志監(jiān)控(Prometheus)6 個(gè)插件展開(kāi)功能測(cè)試和分析。
在實(shí)驗(yàn)室環(huán)境部署和運(yùn)行Nginx+OpenResty+Kong 開(kāi)源軟件系統(tǒng),測(cè)試表明:該系統(tǒng)的配置與更新簡(jiǎn)單快捷,權(quán)限、監(jiān)控、日志等功能均利用Lua腳本實(shí)現(xiàn),通過(guò)加載和卸載工具菜單即可處理,無(wú)需修改配置文件和代碼,且無(wú)需重新啟動(dòng)系統(tǒng)即可使配置生效。同時(shí),該開(kāi)源軟件系統(tǒng)具有少代碼、工具化、開(kāi)箱即用等特點(diǎn),方便系統(tǒng)維護(hù)管理人員使用。
目前,城市軌道交通企業(yè)采用私有云架構(gòu)已成為趨勢(shì)。通過(guò)構(gòu)建云服務(wù)網(wǎng)關(guān)平臺(tái),可以適配和集成服務(wù)、數(shù)據(jù)和應(yīng)用能力,有助于打通內(nèi)部業(yè)務(wù)流和數(shù)據(jù)流,促進(jìn)企業(yè)數(shù)字化運(yùn)營(yíng)水平提升,助力企業(yè)業(yè)務(wù)創(chuàng)新。
API 網(wǎng)關(guān)技術(shù)體系中有許多優(yōu)秀的開(kāi)源和商用軟件。在滿足城市軌道交通應(yīng)用需求方面,本文研究的開(kāi)源軟件框架還存在一些欠缺之處;如協(xié)議轉(zhuǎn)換只支持HTTP/SOAP/gRPC,城市軌道交通中工控設(shè)備較多,目前尚無(wú)支持MQTT(消息隊(duì)列遙測(cè)傳輸協(xié)議)、Modbus 等協(xié)議轉(zhuǎn)換的開(kāi)源組件;另外,動(dòng)態(tài)路由需要通過(guò)Lua+Redis 自定義開(kāi)發(fā)實(shí)現(xiàn);尚不能與MQ 集成,無(wú)法使用訂閱發(fā)布機(jī)制。下一步需結(jié)合具體業(yè)務(wù)場(chǎng)景,在應(yīng)用實(shí)踐中進(jìn)一步研究和解決這些問(wèn)題。