何運田 張青清
(中國銀聯(lián)股份有限公司 上海 200120)
隨著云計算[1]和互聯(lián)網(wǎng)技術的快速發(fā)展,越來越多的企業(yè)開始重視微服務[2-3]、云原生等新一代技術架構設計模式。以國內為例,知名互聯(lián)網(wǎng)公司都開始發(fā)力云技術,逐步對外提供獨立自主開發(fā)的公有云產(chǎn)品,比如阿里云、華為云、騰訊云等。這些云平臺不僅很好地支撐了各自企業(yè)內部的需求,也為不具備開發(fā)云平臺能力的廣大中小企業(yè)提供了開箱即用的云產(chǎn)品,滿足了應用上云的需求。云上應用大多數(shù)采用微服務的架構;在各類業(yè)務場景中,一個業(yè)務系統(tǒng)往往分解成若干個子系統(tǒng)。子系統(tǒng)之間以API為形態(tài),進行跨系統(tǒng)跨組織的開放、共享、重組和調用。如果在服務資源入口不做統(tǒng)一的管理,紛亂的協(xié)議、不同格式的網(wǎng)絡數(shù)據(jù)、繁雜的調用拓撲會讓整個服務集成和運維的過程變得異常復雜和不穩(wěn)定。因此,如何有效地治理和管控各個業(yè)務子系統(tǒng),并通過有效的監(jiān)控手段來保障微服務功能有效、安全可靠,將成為各團隊組織上云之前必須考慮的問題[4]。
為了解決上述問題,本文基于開源技術,設計并搭建了一套API網(wǎng)關集成及監(jiān)控系統(tǒng),并在公司的私有云環(huán)境中進行了部署和實踐,取得了很好的效果。系統(tǒng)整體架構如圖1所示。
圖1 整體系統(tǒng)架構
根據(jù)圖1,系統(tǒng)整體上劃分成兩個VPC(虛擬私有云):VPC1(內部局域網(wǎng))和VPC2(互聯(lián)網(wǎng)連接區(qū))。VPC1隸屬公司生產(chǎn)區(qū),有嚴格的防火墻控制,具備較高的安全策略;VPC2類似通常所說的DMZ區(qū),可以通過配置有限的連接互聯(lián)網(wǎng)。兩個網(wǎng)絡之間通過對等網(wǎng)絡連接,這樣VPC1和VPC2可以通過私有IP地址進行通信,就像兩個VCP在一個網(wǎng)絡中一樣。為了實現(xiàn)高可用,VPC1和VPC2之間以及VPC2和互聯(lián)網(wǎng)之間都增設了負載均衡設備,既增強系統(tǒng)穩(wěn)定性,也在一定程度上屏蔽了VPC之間網(wǎng)絡的復雜性[5]。
除了網(wǎng)絡上的職責劃分,系統(tǒng)在功能上分成三個部分:
(1) 服務集成網(wǎng)關。Kong是一個在Nginx中運行的開源Lua應用程序,兼具了Nginx優(yōu)秀的反向代理功能和Lua-Nginx模塊的擴展特性?;贙ong技術設計API網(wǎng)關,可以很容易通過插件的形式來擴展負載均衡、日志審計、身份驗證、速率限制、請求轉換等非業(yè)務功能。為了統(tǒng)一管理的微服務之間的互相調用,所有的微服務開放的API統(tǒng)一遵循RESTful[6]的風格。該風格的接口通過每個URI代表一種資源,客戶端通過HTTP協(xié)議來對服務端資源進行操作,并獲取JSON格式的結果。
(2) 網(wǎng)關管理平臺。為了更方便運維人員可視化配置及管理API,本系統(tǒng)以KONGA開源項目為藍本,進行二次開發(fā)。使用人員可以很方便地通過網(wǎng)關管理平臺對Kong集群進行配置。
(3) 網(wǎng)關監(jiān)控系統(tǒng)。監(jiān)控系統(tǒng)由Dashboard(智能監(jiān)控大屏)、Kong-syncer(日志同步服務器)、Monitor-server(監(jiān)控后臺服務器)三部分組成。通過監(jiān)控系統(tǒng),不僅可以實時采集并查看網(wǎng)關中配置的API訪問信息,還可以按需進行聚合分析等增值服務。
單體服務不需要API維度的網(wǎng)關,因為它匯總了一個業(yè)務系統(tǒng)所提供的所有API,可以統(tǒng)一對這些服務做調度、鑒權、限流等控制。但在微服務架構的應用中,因為功能模塊的拆分,每個子業(yè)務系統(tǒng)都會獨立提供服務;這些服務有可能互相之間進行調度,也可能對外提供服務。面向微服務的API網(wǎng)關[7]定位于解決對外提供服務這塊內容,通常也稱之為邊緣服務。它的定義為類似面向對象設計模式中的Facade模式,它的存在就像整個微服務架構系統(tǒng)中的門面一樣,所有的外部客戶端訪問云平臺,都需要經(jīng)過網(wǎng)關來做統(tǒng)一的調度和管控。具體而言,主要體現(xiàn)在以下方面:
(1) 服務統(tǒng)一管理。其包括對服務接口格式、元數(shù)據(jù)、服務提供方、服務消費方等的管理。涵蓋API的上線、發(fā)布、下線等整個生命周期。
(2) 服務調用管理。主要體現(xiàn)在權限控制方面,比如調用權限的認證過濾、調用頻次、調用總額、黑白名單等。
(3) 服務質量(QoS)控制。網(wǎng)關為上游服務提供多種策略來解決應用過程中可能出現(xiàn)的服務性能問題,比如負載均衡、緩存、熔斷、降級、流量控制等,以提高服務的穩(wěn)定性和可用性。
(4) 服務監(jiān)控與報警。微服務體系中因系統(tǒng)繁多、交互復雜,更需要有較好的運維監(jiān)控和報警體系。網(wǎng)關系統(tǒng)需要從用戶、服務、應用多種維度分析統(tǒng)計API調用情況,并針對可能出現(xiàn)和已經(jīng)出現(xiàn)的問題進行及時預警和報警。
本系統(tǒng)中,網(wǎng)關集群是基于開源技術Kong[8]來實現(xiàn)。Kong是Mashape公司的開源API網(wǎng)關,其底層是基于Nginx驅動的,幾乎沒有任何性能消耗,性能可以達到1 600次/s,增加安全鑒權后訪問也沒有明顯性能下降,性能跟原生Nginx不相上下。
Kong支持主流數(shù)據(jù)庫的讀寫,目前官方給定的選擇包括PostgreSQL和Cassandra。因為Cassandra[9]具備較成熟的集群解決方案,因此本文中采用Kong+Cassandra來組成集群。由于Kong本身不具備集群能力,因此需要配置前置負載來實現(xiàn)Kong節(jié)點之間的流量均衡。該方案可以使Kong支持更多的訪問流量,同時保證較低的網(wǎng)絡延遲。出于性能考量,為了避免頻繁的數(shù)據(jù)訪問,集群中的每個節(jié)點都會在本地緩存一部分數(shù)據(jù)。
另外,Kong具備模塊性。開發(fā)者可以通過給Kong節(jié)點增加插件的方式來擴展網(wǎng)關的功能。官方已經(jīng)提供了很多可以開箱即用的插件,比如Auth2.0、logging、CORS(Cross-Origin Resource Sharing)等。開發(fā)者也可以通過Lua語言編寫自定義插件,并通過Lua-Nginx-module模塊來集成進Nginx[10]的生命周期中。具體集群架構見圖2。
圖2 Kong集群架構
Kong提供了完善的管理接口,用來對Kong實現(xiàn)管理功能。默認情況下,Kong服務會監(jiān)聽8001端口用于管理API的響應,監(jiān)聽8000端口用來接收需要轉發(fā)的RestFul請求。為了方便管理API,Kong抽象了若干個概念:
(1) 服務(Service)。服務等價于Nginx的upstream指令中的server,用來代指上游的真實服務。當有多個上游服務實例時,可以配置權重來實現(xiàn)流量分配。
(2) 路由(Route)。路由定義了匹配客戶端請求的路徑規(guī)則,一個服務可以包含若干路由。
(3) 消費者(Consumer)。消費者代指一個服務接入方,可以根據(jù)消費者的ID來對特定路由設置訪問權限。
(4) 插件(Plugin)。插件代指想要對Kong擴展的小功能,比如日志插件,可以在請求到網(wǎng)關時,記錄日志到數(shù)據(jù)庫。插件使用Lua語言開發(fā),通過Kong的管理端口來啟用,使得功能定制化擴展非常方便。
以上概念是Kong的核心概念,也是我們管理Kong網(wǎng)關的主要目標。由于Kong提供了管理接口,我們可以通過命令行Curl進行配置,以創(chuàng)建OCR識別應用的API轉發(fā)為例,配置命令如下:
curl -X POST "http:kongHost:8001/apis/
-H ′Content-Type: application/json′
-d ′{
"name": "ocr_api",
"uris": "OCR",
"upstream_ url": "http://OCR_ HOST",
"strip _ uri": " true"
}′
考慮到Curl的配置方式對使用者來說不是很友好,而且容易出錯,本系統(tǒng)以開源項目KongA為基礎,進行了二次開發(fā),實現(xiàn)了Kong的可視化配置,簡化了操作。具體管理界面效果見圖3。
圖3 KongA配置Service示意圖
很多時候,服務的提供者和服務的調用者都有監(jiān)控服務的性能、服務調用量、網(wǎng)絡帶寬、出錯告警等需求。因此,一個成熟的網(wǎng)關系統(tǒng)少不了監(jiān)控體系。本系統(tǒng)針對這部分需求,采用集成開源分布式搜索引擎Elasticsearch[11]加自研組件的方式,實現(xiàn)客戶端API請求的日志存儲、分析及實時監(jiān)控預警等功能。其中,Elasticsearch具體的架構如圖4所示。
圖4 監(jiān)控子系統(tǒng)架構示意圖
如圖4所示,監(jiān)控子系統(tǒng)主要包括Dashboard、monitor、Elasticsearch集群,以及自研數(shù)據(jù)同步集群Kong-syncer。其中:Dashboard主要負責對外實時展示各種統(tǒng)計圖表;monitor用來管理及實現(xiàn)統(tǒng)計邏輯;Elasticsearch集群負責存儲、搜索、聚合各種日志信息;Kong-syncer類似ETL工具,用來從數(shù)據(jù)源監(jiān)聽拉取原始數(shù)據(jù),清洗及格式化后導入ES集群。
Kong本身具備模塊特性,支持自定義插件來擴展所需功能。本系統(tǒng)啟用http-log插件,在Kong接收到客戶端請求的響應所有body信息時會自動將請求的日志信息發(fā)送到自研的sync-server進行歸并并存儲到ES集群。啟動日志插件可以通過管理平臺來可視化完成操作。為了方便后續(xù)的統(tǒng)計和分析,針對請求的日志格式需要具備良好的擴展性和可讀性。本系統(tǒng)采用JSON的格式來定義和解析日志,日志格式如下:
{
"request": {
"method": "請求方式",
"uri": "請求URI",
"url": "完整請求路徑",
"size": "請求體",
"querystring": ["請求參數(shù)組"],
"headers": ["請求頭鍵值對"]
},
"upstream_uri": "上游服務轉發(fā)路徑",
"response": {
"status": "響應code",
"size": "響應大小",
"headers": ["響應頭鍵值對"]
},
"route": {
"id": "請求匹配的路由Id",
"paths": ["匹配的路徑數(shù)據(jù)"],
"service": {
"id": "關聯(lián)的service ID"
}
},
"service": {
"host": "匹配的服務的host",
"id": "匹配服務的ID",
"name": "服務名",
"path": "服務路徑 ",
"port": "服務端口",
"protocol": "服務協(xié)議"
},
"consumer": {
"username": "請求業(yè)務方的名字"
},
"latencies": {
"proxy": "代理延遲",
"kong": " 網(wǎng)關本身的延遲",
"request": " 請求處理的延遲時長"
},
"client_ip": "業(yè)務方IP",
"started_at": " 請求的時間戳"
}
Elasticsearch是一個基于Lucene的搜索服務器。它提供了一個分布式多用戶能力的全文搜索引擎,基于RESTful web接口。ElasticSearch用于云計算中,能夠達到實時搜索、穩(wěn)定、可靠、快速。本系統(tǒng)采用ES集群作為日志的持久化組件,既能滿足JSON格式的文本存儲的需求,又能利用Elastic開放的RestFul接口,實現(xiàn)日志的統(tǒng)計查詢和聚合功能。
根據(jù)請求的路由id來查詢當日訪問量top5的Api為例,利用Elasticsearch的msearch接口,就可以通過以下post請求來實現(xiàn),非常靈活便捷。
curl -X POST "http://es_host:9200/_msearch
-H ′Content-Type: application/json′ -d
{"index":"kong","ignore_unavailable":true,"timeout":30000,"preference":1580535845202}
{"aggs":{"top5":{"terms":{"field":"route.id","size":5,"order":{"_count":"desc"}}}},"size":0,"version":true,"stored_fields":["*"],"docvalue_fields":[{"field":"request.headers.date","format":"date_time"},{"field":"startedAt","format":"date_time"}],"query":{"bool":{"must":[{"match_all":{}},{"range":{"startedAt":{"gte":"startTime","lte":"endTime","format":"epoch_millis"}}},{"bool":{"should":["filtersArray"],"minimum_should_match":1}}]}}}
查詢的結果通過解析處理后就可以按照約定的格式發(fā)送給前端的Dashboard進行展示;用戶可以決定是在大屏上顯示,還是通過H5頁面嵌入的方式在移動端顯示。以移動端顯示為例,部分效果如圖5所示。
圖5 監(jiān)控平臺移動端展示Dashboard
為了解決實際私有云環(huán)境中API網(wǎng)關的建設及監(jiān)控運維問題,本文以Kong、Elasticsearch等開源組件為基礎,結合自有編碼,設計并實踐了一套API網(wǎng)關及監(jiān)控體系,取得了很好的效果。通過API集成網(wǎng)關,私有云可以按照統(tǒng)一格式轉發(fā)、配置、管理、監(jiān)控所有的API請求,實現(xiàn)了API接口的統(tǒng)一管理和運維,減少了開發(fā)人員和接口使用方的工作量,也減少了二次人員開發(fā)學習的成本。同時,基于Nginx的網(wǎng)關集群技術也在最大程度保證并發(fā)的同時,兼顧了響應速度。