(遼寧高速通智慧出行有限責(zé)任公司 遼寧 110000)
在拆除省界收費(fèi)站背景下,遼寧高速基于國家政策,遼寧高速統(tǒng)一管理的優(yōu)勢,提出ETC 聚合發(fā)行的構(gòu)想,并積極推動建設(shè)ETC 生態(tài)圈。截至2019 年6 月,遼寧省汽車保有量為800 多萬輛,ETC 用戶僅有240 萬左右,因此ETC 占有比只有20%多。根據(jù)政策要求,在2019 年年底力爭全省新增ETC 用戶420 萬,各市汽車ETC 安裝率在80%以上,通行高速公路車輛ETC 使用率在90%以上。這意味著短時間要完成過去幾年甚至十幾年的發(fā)行量,可以想象任務(wù)之艱巨。傳統(tǒng)ETC 發(fā)行主要在省級發(fā)行方的專業(yè)服務(wù)網(wǎng)點(diǎn)或銀行代理網(wǎng)點(diǎn)進(jìn)行,發(fā)行渠道單一、效率低、體驗(yàn)差、不利于大規(guī)模發(fā)展用戶。在ETC聚合發(fā)行的構(gòu)想下,一方面增加線下網(wǎng)點(diǎn),另一方面重點(diǎn)拓展網(wǎng)上渠道充分發(fā)揮互聯(lián)網(wǎng)渠道優(yōu)勢[1]。
隨著ETC 業(yè)務(wù)大力推廣,各大支付機(jī)構(gòu)、銀行等相繼爭搶ETC在線發(fā)行市場。支付寶、微信、京東、360、中移動、各大銀行等多種渠道開展發(fā)行業(yè)務(wù),因此ETC 在線發(fā)行系統(tǒng)勢必會出現(xiàn)接入方式多樣化、系統(tǒng)請求高并發(fā)、個性化業(yè)務(wù)拓展、系統(tǒng)快速響應(yīng)等特點(diǎn)。而傳統(tǒng)ETC 發(fā)行系統(tǒng)多采用單體架構(gòu)模式實(shí)現(xiàn),單體架構(gòu)將前端頁面、業(yè)務(wù)邏輯處理和數(shù)據(jù)處理等統(tǒng)一編碼在單個應(yīng)用下。在ETC 發(fā)展初期由于業(yè)務(wù)需求單一、業(yè)務(wù)辦理少,采用單體架構(gòu)在代碼開發(fā)、測試、部署、維護(hù)等流程中相對比較簡單高效。但是隨著ETC 業(yè)務(wù)不斷發(fā)展,需求逐漸增多,代碼結(jié)構(gòu)會變得越來越龐大,后期對代碼的整體理解和實(shí)施維護(hù)方面的困難也會增強(qiáng)[2]。再者,單體架構(gòu)在單一進(jìn)程當(dāng)中運(yùn)行,如果遇到系統(tǒng)維護(hù)升級等情況也會導(dǎo)致系統(tǒng)其他功能不可用,從而影響系統(tǒng)的可靠度。因此,單體架構(gòu)應(yīng)用具有業(yè)務(wù)拓展困難、技術(shù)選擇單一、代碼耦合度高、維護(hù)困難、可靠度低等缺點(diǎn)。
2014 年學(xué)者 Martin Fowler 正式提出微服務(wù)架構(gòu)的概念。微服務(wù)架構(gòu)是一種架構(gòu)模式,是指根據(jù)業(yè)務(wù)需求將系統(tǒng)拆分為多個微小服務(wù),服務(wù)獨(dú)立部署在不同的進(jìn)程中,不同服務(wù)通過一些輕量級交互機(jī)制來通信,例如RPC、HTTP 等。服務(wù)可獨(dú)立擴(kuò)展伸縮,每個服務(wù)定義了明確的邊界,不同的服務(wù)可以采用不同的編程語言來實(shí)現(xiàn),由獨(dú)立的團(tuán)隊來維護(hù)[3]。
針對目前ETC 在線發(fā)行業(yè)務(wù)場景和單體架構(gòu)的缺陷,本文將分析微服務(wù)架構(gòu)體系優(yōu)缺點(diǎn)、以及如何基于SpringCloud 微服務(wù)技術(shù)實(shí)現(xiàn)具有前后端分離、高并發(fā)、高可讀、可擴(kuò)展、可獨(dú)立開發(fā)部署等特點(diǎn)的微服務(wù)架構(gòu)系統(tǒng)。
單體結(jié)構(gòu)系統(tǒng)根據(jù)功能拆分為多個微小的服務(wù),每個服務(wù)可單獨(dú)開發(fā)、編譯、部署等,相比單體架構(gòu)微服務(wù)具有以下優(yōu)勢[4]。
(1)降低復(fù)雜度
傳統(tǒng)單體架構(gòu)將所有功能模塊堆積在同一應(yīng)用下,而微服務(wù)架構(gòu)根據(jù)業(yè)務(wù)功能將服務(wù)拆解成多個單體應(yīng)用,不同應(yīng)用可以專注不同的功能實(shí)現(xiàn),因此微服務(wù)結(jié)構(gòu)清晰、功能單一、編碼簡單明了。每個微服務(wù)可獨(dú)立開發(fā)測試維護(hù),模塊之間互不影響,降低模塊間耦合度的同時也提高了代碼的可讀和可維護(hù)性。
(2)可獨(dú)立部署
由于微服務(wù)拆分為多個獨(dú)立的應(yīng)用,因此微服務(wù)可以獨(dú)立部署在單個服務(wù)器容器下,并運(yùn)行在獨(dú)立的進(jìn)程中。當(dāng)業(yè)務(wù)迭代時只需開發(fā)部署相關(guān)服務(wù)即可,降低測試工作量避免了大量回歸測試,同時也降低了服務(wù)發(fā)布的風(fēng)險。
(3)容錯
在微服務(wù)架構(gòu)下,當(dāng)某一組件發(fā)生故障時,故障會被隔離在單個服務(wù)中。通過限流、熔斷等方式降低錯誤導(dǎo)致的危害,保障核心業(yè)務(wù)正常運(yùn)行。
(4)可擴(kuò)展
微服務(wù)擴(kuò)展性可從兩個方面分析,即開發(fā)可擴(kuò)展和部署可擴(kuò)展。開發(fā)可擴(kuò)展是指有新增完整業(yè)務(wù)需求時,可單獨(dú)開辟新的服務(wù)模塊,在不影響現(xiàn)有服務(wù)的情況下,通過獨(dú)立模塊的編碼開發(fā)、測試、部署、完成業(yè)務(wù)需求。部署可擴(kuò)展是指當(dāng)系統(tǒng)訪問量過大時,可通過添加負(fù)載服務(wù)器,解決系統(tǒng)響應(yīng)慢的問題。單體架構(gòu)也可以實(shí)現(xiàn)服務(wù)的橫向擴(kuò)展,但由于單體應(yīng)用包含系統(tǒng)所有的功能,而某些功能訪問頻次并不高,如添加負(fù)載會導(dǎo)致資源的浪費(fèi)。而微服務(wù)可通過監(jiān)控每個服務(wù)的請求量,根據(jù)實(shí)際情況擴(kuò)展不同的服務(wù),合理使用服務(wù)器資源。
任何事務(wù)的出現(xiàn)都具有兩面性,微服務(wù)雖然有很多優(yōu)勢,但同時也有以下幾點(diǎn)缺陷[5]。
增加運(yùn)維成本和開支成本:由于微服務(wù)架構(gòu)是由多個微小服務(wù)組成,需要在多臺服務(wù)器部署且每個服務(wù)會負(fù)載集群,因此服務(wù)器開支成本較高。如果微服務(wù)某個模塊出現(xiàn)異常,往往需要排查整個請求鏈路執(zhí)行情況,而單體架構(gòu)只需在本服務(wù)器根據(jù)日志分析即可,在這個過程中無形增加了運(yùn)維成本。
問題追蹤難度增加:微服務(wù)請求調(diào)用鏈會經(jīng)過多個不同的服務(wù),如一次請求出現(xiàn)問題,需分析請求到達(dá)服務(wù)的狀態(tài)和執(zhí)行結(jié)果,從而增加追蹤問題的復(fù)雜度。
內(nèi)容重復(fù):對部分業(yè)務(wù),流程大致相同時,如果不能很方便將代碼封裝,就可能導(dǎo)致在多個服務(wù)中有些重復(fù)性的代碼。除此之外還有日志重復(fù),一個調(diào)用鏈可能要調(diào)用多個服務(wù),在追蹤問題時,每個服務(wù)都要對參數(shù)和響應(yīng)進(jìn)行記錄,這樣就導(dǎo)致相同日志內(nèi)容重復(fù)出現(xiàn)在多個地方。
傳統(tǒng)ETC 設(shè)備申請需客戶攜帶身份證原件、駕駛證原件、自駕辦理車輛前往附近ETC 營業(yè)廳進(jìn)行辦理。然而營業(yè)廳辦理會給用戶帶來很多不便,如遇到客戶資料不全、附近沒有營業(yè)廳網(wǎng)點(diǎn)、辦理人員太多等情況都可能導(dǎo)致用戶辦理中斷。隨著省界收費(fèi)站拆除和ETC 大力推廣,傳統(tǒng)辦理模式已不能滿足當(dāng)前需求。為應(yīng)對ETC 業(yè)務(wù)的不斷擴(kuò)張、減少客戶出行、節(jié)省用戶時間,從而提出ETC 社會化在線發(fā)行需求??蛻艚柚鶤PP 客戶端或微信小程序在線提交客戶身份證、車輛行駛證、銀行卡、郵寄地址等信息申請ETC 設(shè)備,后臺審核用戶訂單信息,如客戶信息填寫正確,業(yè)務(wù)人員將ETC 設(shè)備郵寄給客戶??蛻羰盏轿醇せ畹脑O(shè)備,通過APP 客戶端或微信小程序等自助在線激活設(shè)備。根據(jù)需求分析可分為如下幾個功能:
H5 新辦模式主要對接銀聯(lián)、工行、建行、農(nóng)行、郵儲、中行、農(nóng)信社等銀行接入方。各接入方客戶端APP 通過調(diào)用ETC 社會化發(fā)行接口拉起新辦H5頁面,首頁展示新辦相關(guān)協(xié)議,用戶勾選同意后,點(diǎn)擊下一步,跳轉(zhuǎn)到車輛信息頁。此頁需上傳用戶行駛本正反面,填寫車牌號車牌顏色。點(diǎn)擊下一步,調(diào)用后臺接口校驗(yàn)車牌是否在黑名單以及是否已發(fā)行。校驗(yàn)通過后進(jìn)入開戶人信息頁,此頁填寫開戶人姓名、身份證信息。點(diǎn)擊下一步,后臺服務(wù)將姓名、身份證號等關(guān)鍵信息傳遞給銀行,進(jìn)行一次簽約校驗(yàn),銀行校驗(yàn)用戶信息是否填寫正確。校驗(yàn)通過后,銀行給用戶發(fā)送短信驗(yàn)證碼,頁面跳轉(zhuǎn)到下一頁,用戶輸入校驗(yàn)碼。點(diǎn)擊下一步,后臺將用戶手機(jī)號、驗(yàn)證碼等信息上送給銀行,進(jìn)行二次簽約校驗(yàn)。校驗(yàn)通過后,后臺服務(wù)將訂單提交到內(nèi)部發(fā)行核心系統(tǒng),完成新辦訂單提交。
我們知道H5 新辦模式只需接入方調(diào)用后臺接口拉起H5 頁面,并提供一次簽約和二次簽約接口相關(guān)接口即可。雖然H5 模式方便商戶接入,但是H5頁面風(fēng)格固定并不能滿足其他商戶頁面?zhèn)€性化需求。而原生新辦模式是指社會化發(fā)行系統(tǒng)只提供用戶車輛信息提交、身份信息提交、校驗(yàn)車輛是否在黑名單、校驗(yàn)車輛是否已發(fā)行、訂單提交等接口服務(wù),前端頁面由各接入方自行實(shí)現(xiàn)。接入方可自行選擇通過安卓或IOS 系統(tǒng)原生APP、微信或支付寶小程序來實(shí)現(xiàn)前端頁面,這樣可以滿足不同商戶頁面?zhèn)€性化需求。
新辦訂單出庫后,用戶收到的設(shè)備(ETC 卡OBU 標(biāo)簽)是未激活狀態(tài)。用戶需通過微信小程序、APP 等渠道自助激活設(shè)備。其中設(shè)備激活分為標(biāo)簽激活和卡激活兩部分。系統(tǒng)主要提供寫標(biāo)簽車輛信息、寫標(biāo)簽系統(tǒng)信息、寫標(biāo)簽結(jié)果確認(rèn)、卡片個人化、卡片系統(tǒng)化等服務(wù)。
用戶在使用過程中遇到特殊情況,如損壞標(biāo)簽、損壞ETC 卡或變更車輛信息等情況時,可在線辦理標(biāo)簽更換、ETC 卡更換、車輛信息變更、卡注銷、標(biāo)簽二次激活等相關(guān)特殊業(yè)務(wù)。
在ETC 大力推廣的背景下,雖然很多渠道的ETC 設(shè)備是免費(fèi)領(lǐng)取的,但并不意味著所有渠道免費(fèi)或者永久免費(fèi)。如需用戶支付標(biāo)簽費(fèi)用,系統(tǒng)提供微信、支付寶、銀聯(lián)等多種付款渠道。
微服務(wù)是指根據(jù)業(yè)務(wù)功能合理拆分為多個可獨(dú)立部署維護(hù)的子服務(wù)。微服務(wù)的拆分方案是決定系統(tǒng)是否具備高內(nèi)聚、松耦合、可擴(kuò)展、高可讀等特性的關(guān)鍵所在。
從ETC 社會化發(fā)行業(yè)務(wù)功能章節(jié)分析可將服務(wù)拆分為新辦訂單、設(shè)備激活、特殊業(yè)務(wù)、支付服務(wù)等模塊,每個模塊完成各自領(lǐng)域內(nèi)業(yè)務(wù)互不干擾。鑒于新辦訂單、激活、特殊業(yè)務(wù)等需調(diào)用內(nèi)部核心發(fā)行系統(tǒng)完成,為減少冗余代碼提高代碼復(fù)用率,提取出第三方發(fā)行模塊。第三方發(fā)行模塊調(diào)用核心發(fā)行系統(tǒng)服務(wù)并對內(nèi)部服務(wù)提供接口,如此提高代碼復(fù)用率的同時使以上三個模塊更專注于業(yè)務(wù)邏輯處理。同理,可提取出第三方支付服務(wù)。由于微服務(wù)不會開放所有的功能,增加用戶鑒權(quán)服務(wù)可保護(hù)數(shù)據(jù)服務(wù)安全。系統(tǒng)拆分如表1 所示。
表1 系統(tǒng)拆分表
(1)技術(shù)選型
ETC 社會化發(fā)行采用的是前后端分離可獨(dú)立部署維護(hù)的微服務(wù)系統(tǒng)架構(gòu)。后臺提供REST 風(fēng)格接口,既支持各接入方系統(tǒng)直接調(diào)用,又支持接入方客戶端嵌入H5 頁面進(jìn)行調(diào)用。前端采用VUE 框架,VUE 是一個輕量級MVVM 即數(shù)據(jù)雙向綁定架構(gòu)模式,可減少開發(fā)人員頻繁操作DOM 文檔,方便開發(fā)人員專注于業(yè)務(wù)邏輯處理。目前微服務(wù)架構(gòu)主流的技術(shù)有Dubbo 和SpringCloud。Dubbo 是一款開源的輕量級、高性能Java RPC 遠(yuǎn)程調(diào)用框架,其提供了三大核心能力:面向接口的遠(yuǎn)程方法調(diào)用,智能容錯和負(fù)載均衡,以及服務(wù)自動發(fā)現(xiàn)和注冊。SpringCloud 是一個完整的微服務(wù)解決方案,其提供注冊中心、配置中心、網(wǎng)關(guān)、鏈路追蹤、Fegin 遠(yuǎn)程調(diào)用、斷路器、消息總線等一系列組件。經(jīng)過對比,Dubbo 是一款輕量級RPC 框架,而SpringCloud 是專注于微服務(wù)領(lǐng)域的具有全套解決方案的框架。本文采用SpringCloud 技術(shù)來實(shí)現(xiàn)ETC 社會化發(fā)行微服務(wù)后臺。
(2)架構(gòu)設(shè)計
從微服務(wù)技術(shù)角度分析以下三個服務(wù)必不可少。網(wǎng)關(guān)服務(wù):網(wǎng)關(guān)服務(wù)是微服務(wù)架構(gòu)的統(tǒng)一入口,其核心功能是路由轉(zhuǎn)發(fā)與過濾器。路由轉(zhuǎn)發(fā)類似于Nginx 反向代理,可根據(jù)路由規(guī)則將請求轉(zhuǎn)發(fā)到對應(yīng)微服務(wù)。注冊中心:注冊中心記錄了微服務(wù)和服務(wù)地址之間的映射關(guān)系,承擔(dān)服務(wù)注冊與發(fā)現(xiàn)功能。配置中心:配置中心就是把項目中各種配置、各種參數(shù)、各種開關(guān),全部都放到一個集中的地方進(jìn)行統(tǒng)一管理,并提供一套標(biāo)準(zhǔn)的接口。當(dāng)各個服務(wù)需要獲取配置的時候,就來配置中心的接口拉取。當(dāng)配置中心中的各種參數(shù)有更新的時候,也能通知到各個服務(wù)及時同步最新的信息,使之動態(tài)更新。
通過ETC 社會化發(fā)行業(yè)務(wù)功能、服務(wù)拆分、技術(shù)選型等分析,確定了微服務(wù)總體架構(gòu)。可將系統(tǒng)架構(gòu)分為應(yīng)用層、接入層、平臺服務(wù)層、數(shù)據(jù)層、基礎(chǔ)支撐層。系統(tǒng)架構(gòu)圖如圖1 所示。
應(yīng)用層:直接面向用戶可視化操作的H5 頁面或各接入方客戶端應(yīng)用。
接入層:接入層是指微服務(wù)的統(tǒng)一入口,接收客戶端所有請求,并根據(jù)地址與服務(wù)路由規(guī)則將請求轉(zhuǎn)發(fā)到對應(yīng)微服務(wù)。網(wǎng)關(guān)服務(wù)不僅有路由轉(zhuǎn)發(fā)功能,還包括服務(wù)鑒權(quán)、系統(tǒng)限流等功能。
平臺服務(wù)層:平臺服務(wù)層指從業(yè)務(wù)功能與SpringCloud 微服務(wù)技術(shù)體系角度拆分的具體服務(wù)。從業(yè)務(wù)服務(wù)分為新辦訂單、特殊業(yè)務(wù)、設(shè)備激活、用戶鑒權(quán)等。從微服務(wù)組件分為注冊中心、配置中心、基于Hystrix 斷路器組件、基于Ribbon 的負(fù)載均衡組件、基于Sleuth 鏈路追蹤組件、SpringBoot Admin 微服務(wù)監(jiān)控服務(wù)等。
數(shù)據(jù)層:主要指Mongo 數(shù)據(jù)庫實(shí)例、Redis 緩存等。
基礎(chǔ)支撐層:包括服務(wù)器、網(wǎng)絡(luò)設(shè)備、等支撐系統(tǒng)的物理組件。
圖1 系統(tǒng)架構(gòu)圖
隨著業(yè)務(wù)的發(fā)展,系統(tǒng)功能越來越復(fù)雜,微服務(wù)數(shù)量也不斷增加。并且服務(wù)的集群規(guī)模、服務(wù)位置、服務(wù)命名等都可能發(fā)生變化。傳統(tǒng)模式下服務(wù)調(diào)用方需要單獨(dú)維護(hù)服務(wù)提供方地址,這樣不僅增加了維護(hù)的復(fù)雜度而且當(dāng)服務(wù)提供方地址變更或者新增負(fù)載服務(wù)后調(diào)用方也不能動態(tài)感知。為解決此類問題,微服務(wù)架構(gòu)體系提出服務(wù)治理概念,用于解決微服務(wù)的注冊與發(fā)現(xiàn)問題。
Eureka 是SpringCloud 微服務(wù)體系中專為服務(wù)治理構(gòu)建的組件。Eureka 服務(wù)治理主要包括服務(wù)注冊中心、服務(wù)提供者、服務(wù)消費(fèi)者三個要素。注冊中心是Eureka 提供的服務(wù)端,主要用于提供服務(wù)注冊與發(fā)現(xiàn)功能。服務(wù)提供者提供具體服務(wù)的應(yīng)用,將自身服務(wù)注冊到注冊中心,供消費(fèi)者發(fā)現(xiàn),其中主要功能包括服務(wù)注冊、服務(wù)同步、服務(wù)續(xù)約等。服務(wù)消費(fèi)者從注冊中心拉取服務(wù)列表,消費(fèi)者根據(jù)需求調(diào)用具體服務(wù),其中主要功能包括獲取服務(wù)、服務(wù)調(diào)用、服務(wù)下線等[6]。Eureka 各元素之間通信關(guān)系如圖2 所示。基于本系統(tǒng)架構(gòu),API 網(wǎng)關(guān)、各業(yè)務(wù)服務(wù)以及微服務(wù)組件等都會通過Eureka 進(jìn)行服務(wù)注冊與發(fā)現(xiàn),Eureka 維護(hù)消費(fèi)端以及服務(wù)端的綁定關(guān)系。例如消費(fèi)端API網(wǎng)關(guān)服務(wù)通過注冊中心查找定位具體的服務(wù)端服務(wù)。
Spring Cloud Ribbon 是一個基于Http 和TCP 的客服端負(fù)載均衡工具,它是基于Netflix Ribbon 實(shí)現(xiàn)的。它不像服務(wù)注冊中心、配置中心、API 網(wǎng)關(guān)那樣獨(dú)立部署,但是它幾乎存在于每個微服務(wù)的基礎(chǔ)設(shè)施中,SpringCloud 微服務(wù)體系中Zuul 和Fegin 等組件就是基于Ribbon 來實(shí)現(xiàn)路由轉(zhuǎn)發(fā)或者客戶端調(diào)用。Ribbon 有很多負(fù)載均衡算法,最簡單算法來自著名的 Round Robin 算法,即輪詢法[7]。其思想是根據(jù)服務(wù)實(shí)例組成的集合,按照順序依次循環(huán)調(diào)用,另外還有加權(quán)輪詢[8]、最小連接數(shù)算法等[9]。
圖2 Eureka 各元素通訊圖
微服務(wù)是由很多服務(wù)組合而成的系統(tǒng),每個服務(wù)都需要鑒權(quán)、限流、權(quán)限校驗(yàn)等功能。如果每個服務(wù)都對外暴露接口,各自實(shí)現(xiàn)鑒權(quán)、限流等邏輯。這樣不僅會生成代碼冗余,而且造成客戶端調(diào)用地址多,維護(hù)很不方便。更好的解決方案是提供API 網(wǎng)關(guān),API 網(wǎng)關(guān)作為微服務(wù)統(tǒng)一入口,類似Nginx 反向代理,將客戶端所有請求路由到服務(wù)端進(jìn)行處理。當(dāng)然網(wǎng)關(guān)不是單純轉(zhuǎn)發(fā)功能,還可針對流量進(jìn)行擴(kuò)展,比如鑒權(quán)、限流、權(quán)限校驗(yàn)、簽名驗(yàn)簽、日志等。通過引入網(wǎng)關(guān),客戶端無須關(guān)心后臺調(diào)用哪些服務(wù),只需要與網(wǎng)關(guān)進(jìn)行交互。網(wǎng)關(guān)引入帶來方便的同時也伴隨著安全隱患,如果網(wǎng)關(guān)服務(wù)不穩(wěn)定、響應(yīng)效率低等都可能導(dǎo)致服務(wù)不可用。ETC 社會化發(fā)行系統(tǒng)采用網(wǎng)關(guān)作為系統(tǒng)的唯一入口,實(shí)現(xiàn)了請求響應(yīng)日志信息統(tǒng)一打印,借助網(wǎng)關(guān)過濾器實(shí)現(xiàn)了請求信息簽名驗(yàn)簽、用戶鑒權(quán)等功能,有效解耦業(yè)務(wù)功能與非業(yè)務(wù)功能代碼。
本文采用SpringCloud Zuul 組件實(shí)現(xiàn)微服務(wù)網(wǎng)關(guān)服務(wù),Zuul 不僅具有動態(tài)路由功能,還可通過過濾器組件自定義實(shí)現(xiàn)微服務(wù)安全認(rèn)證、簽名驗(yàn)簽等功能。動態(tài)路由與負(fù)載均衡:當(dāng)客戶端請求進(jìn)入網(wǎng)關(guān)服務(wù),Zuul 根據(jù)微服務(wù)實(shí)例名與路徑匹配關(guān)系,自動將請求轉(zhuǎn)發(fā)到服務(wù)端。Zuul 路由轉(zhuǎn)發(fā)通過Ribbon 組件實(shí)現(xiàn),Ribbon 根據(jù)自定義配置將請求動態(tài)負(fù)載到微服務(wù),從而實(shí)現(xiàn)微服務(wù)高并發(fā)。安全認(rèn)證:由于Http 請求是無狀態(tài)的,服務(wù)端無法區(qū)分安全訪問和非法訪問??蛻舳苏埱蠓?wù)提供的接口時,他們訪問的權(quán)限往往需要有一定限制,系統(tǒng)不會將所有接口對外開放。然后Zuul 組件默認(rèn)路由并沒有校驗(yàn)權(quán)限,為此需要借助zuul 組件另外核心功能過濾器ZuulFilter 來實(shí)現(xiàn)請求攔截。在過濾器中實(shí)現(xiàn)權(quán)限校驗(yàn)邏輯,校驗(yàn)通過才能請求微服務(wù)[10]。
在微服務(wù)架構(gòu)中,系統(tǒng)拆分成了多個微小服務(wù),各微服務(wù)之間通過服務(wù)注冊與發(fā)現(xiàn)的方式互相依賴。由于每個服務(wù)運(yùn)行在不同的進(jìn)程,通過遠(yuǎn)程調(diào)用方式互相通訊,這樣很可能出現(xiàn)網(wǎng)絡(luò)延遲或者被調(diào)用服務(wù)本身故障,因此導(dǎo)致調(diào)用方的對外服務(wù)也出現(xiàn)延遲,若此時調(diào)用方請求不斷增加,最后調(diào)用方可能出現(xiàn)無法響應(yīng)而形成任務(wù)積壓,線程資源無法釋放,最終導(dǎo)致自身服務(wù)的癱瘓,甚至出現(xiàn)故障蔓延導(dǎo)致整個服務(wù)不可用。為了解決這樣的問題,因此產(chǎn)生了斷路器等一系列的服務(wù)保護(hù)機(jī)制。
針對上述問題,在Spring Cloud Hystrix 中實(shí)現(xiàn)了斷路器、線程隔離等服務(wù)保護(hù)功能。它是基于Netflix 的開源框架 Hystrix 實(shí)現(xiàn)的,該框架目標(biāo)在于通過控制那些訪問遠(yuǎn)程系統(tǒng)、服務(wù)和第三方庫的節(jié)點(diǎn),從而對延遲和故障提供更強(qiáng)大的容錯能力。Hystrix 具備了服務(wù)降級、服務(wù)熔斷、線程隔離、請求緩存、請求合并及服務(wù)監(jiān)控等強(qiáng)大功能[6]。例如網(wǎng)關(guān)服務(wù)通過Ribbon 路由到各級服務(wù),Ribbon 默認(rèn)實(shí)現(xiàn)了斷路器功能,當(dāng)下級服務(wù)出現(xiàn)異常時能快速響應(yīng),避免大量請求堆積到網(wǎng)關(guān)從而導(dǎo)致整個服務(wù)不可用。
根據(jù)遼寧省ETC 發(fā)行需求可知,在2019 年下半年要完成過去幾年甚至十幾年ETC 發(fā)行量的2-3 倍??上攵?,系統(tǒng)在這段時間要承擔(dān)大量的請求數(shù),因此系統(tǒng)要具備高并發(fā)以及高可用等特點(diǎn)。高并發(fā)是系統(tǒng)并行處理大量請求的能力,主要體現(xiàn)在系統(tǒng)快速響應(yīng)、高吞吐量、高并發(fā)用戶量等指標(biāo)。高可用是指系統(tǒng)是否具備穩(wěn)定運(yùn)行的能力,比如某服務(wù)異常不可用時是否有備份提供服務(wù),主要解決服務(wù)單點(diǎn)故障問題。
系統(tǒng)高并發(fā)可從垂直擴(kuò)展和水平擴(kuò)展方面出發(fā)。垂直擴(kuò)展:一提高單機(jī)硬件處理能力,比如增加系統(tǒng)內(nèi)存、增加系統(tǒng)內(nèi)核數(shù)等。二提高微服務(wù)快速響應(yīng)能力。使用緩存將系統(tǒng)常用的用戶信息、商戶信息等基礎(chǔ)數(shù)據(jù)、以及更新頻次多查詢慢的統(tǒng)計數(shù)據(jù)放置在JVM 內(nèi)存中,減少頻繁的數(shù)據(jù)庫查詢以及頻繁的IO 操作。使用線程池減少頻繁創(chuàng)建線程所占用的資源和時間,比如數(shù)據(jù)庫連接線程池。優(yōu)化查詢語句,數(shù)據(jù)查詢在業(yè)務(wù)處理占比很高,通過優(yōu)化查詢語句以及表結(jié)構(gòu)添加索引等手段,可有效解決系統(tǒng)響應(yīng)慢的問題。水平擴(kuò)展,垂直擴(kuò)展可提高單體服務(wù)的處理能力,但單機(jī)服務(wù)器處理能力有限面對高并發(fā)請求往往會出現(xiàn)請求丟失、內(nèi)存溢出、連接超時等情況。微服務(wù)特點(diǎn)是通過分析,將業(yè)務(wù)量大、頻繁使用的業(yè)務(wù)模塊進(jìn)行水平擴(kuò)展。水平擴(kuò)展是將微服務(wù)整體部署在新服務(wù)器下,可根據(jù)需求部署多臺服務(wù),可精準(zhǔn)定位減少資源浪費(fèi)并且有效解決系統(tǒng)高并發(fā)問題。
系統(tǒng)高可用是指系統(tǒng)是否具備穩(wěn)定的運(yùn)行能力,如網(wǎng)關(guān)服務(wù)、注冊中心、業(yè)務(wù)服務(wù)等部署在單節(jié)點(diǎn)服務(wù)器,當(dāng)請求量超出瓶頸時可能會出現(xiàn)單點(diǎn)故障。在服務(wù)注冊與發(fā)現(xiàn)段落,我們知道注冊中心Eureka可集群部署,實(shí)現(xiàn)服務(wù)同步,從而達(dá)到互為備份的目的。在服務(wù)路由段落分析,每個微服務(wù)可添加負(fù)載服務(wù)器,Ribbo 可通過負(fù)載策略將請求轉(zhuǎn)發(fā)到“活著”的微服務(wù)下,從而解決單點(diǎn)故障問題。網(wǎng)關(guān)服務(wù)作為微服務(wù)入口,請求方來自用戶,可通過F5、Nginx 反向代理等實(shí)現(xiàn)網(wǎng)關(guān)集群部署等,或者通過keepalive 地址漂移技術(shù)實(shí)現(xiàn)網(wǎng)關(guān)熱備,以達(dá)到網(wǎng)關(guān)高可用。
微服務(wù)特點(diǎn)是服務(wù)多、調(diào)用關(guān)系復(fù)雜,每一次請求鏈路會經(jīng)過多個服務(wù),所以微服務(wù)之間調(diào)用關(guān)系是否能清晰表達(dá)十分重要。通過服務(wù)拆分設(shè)計與架構(gòu)總體設(shè)計分析以及SpringCloud 微服務(wù)技術(shù)特點(diǎn),得到本系統(tǒng)數(shù)據(jù)流向圖如圖3 所示。
圖3 數(shù)據(jù)流向圖
從第1 章分析我們知道微服務(wù)架構(gòu)有復(fù)雜度低、獨(dú)立部署、高容錯、可擴(kuò)展等優(yōu)勢,同時也有運(yùn)維開支成本高、問題追蹤復(fù)雜、內(nèi)容重復(fù)等不足。其中問題追蹤復(fù)雜和內(nèi)容重復(fù)等都與日志打印方式息息相關(guān)。每次請求鏈路會經(jīng)過多個服務(wù)且每個服務(wù)有多臺負(fù)載服務(wù)器,如果服務(wù)出現(xiàn)異常維護(hù)人員需要通過查找鏈路經(jīng)過的所有服務(wù)日志來定位問題,因此追蹤問題變得異常復(fù)雜。針對現(xiàn)有問題,如果微服務(wù)日志統(tǒng)一收集在一個服務(wù)器且能通過唯一標(biāo)識搜索每次請求鏈路上所有日志,這樣不僅能減少開發(fā)人員定位問題難度還能減少重復(fù)日志打印。
ELK Stack 是軟件集合Elasticsearch、Logstash、Kibana 的簡稱,由這三個軟件及其相關(guān)的組件可以打造大規(guī)模日志實(shí)時處理系統(tǒng)。其中,Elasticsearch 是一個基于 Lucene 的、支持全文索引的分布式存儲和索引引擎,主要負(fù)責(zé)將日志索引并存儲起來,方便業(yè)務(wù)方檢索查詢。Logstash 是一個日志收集、過濾、轉(zhuǎn)發(fā)的中間件,主要負(fù)責(zé)將各條業(yè)務(wù)線的各類日志統(tǒng)一收集、過濾后,轉(zhuǎn)發(fā)給 Elasticsearch 進(jìn)行下一步處理。Kibana 是一個可視化工具,主要負(fù)責(zé)查詢 Elasticsearch的數(shù)據(jù)并以可視化的方式展現(xiàn)給業(yè)務(wù)方,比如各類餅圖、直方圖、區(qū)域圖等。ELK 的出現(xiàn)提供了微服務(wù)日志統(tǒng)一收集存儲,并且提供可視化界面減少開發(fā)人員日志查詢工作量。結(jié)合微服務(wù)鏈路追蹤技術(shù),將請求鏈路唯一標(biāo)識存儲于Elasticsearch,通過該唯一標(biāo)識可將鏈路日志一次查出。高并發(fā)情況下微服務(wù)同步日志打印存儲會大大影響程序執(zhí)行效率。本文結(jié)合Logback 日志組件、Redis 消息隊列、ELK 軟件來實(shí)現(xiàn)微服務(wù)日志異步統(tǒng)一收集存儲[11]。ELK 日志處理流程如下圖4 所示。
圖4 ELK 日志處理流程
微服務(wù)系統(tǒng)由多個模塊組成,且每個模塊可部署在多臺服務(wù)器,這樣解決單點(diǎn)故障的同時提高系統(tǒng)高并發(fā)。在生產(chǎn)服務(wù)運(yùn)行當(dāng)中,系統(tǒng)可能會出現(xiàn)很多問題,比如內(nèi)存溢出、磁盤空間不足、系統(tǒng)響應(yīng)超時、服務(wù)異常退出等問題。由于微服務(wù)的系統(tǒng)部署或者網(wǎng)絡(luò)調(diào)用關(guān)系非常復(fù)雜,人工發(fā)現(xiàn)問題變的越來越復(fù)雜,因此微服務(wù)監(jiān)控扮演著重要的角色。
SpringBoot Admin 是一個管理和監(jiān)控SpringBoot 應(yīng)用程序的開源軟件,是在SpringBoot Actuator[12]接口基礎(chǔ)上進(jìn)行UI 美化封裝的監(jiān)控工具。與注冊中心Eureka 結(jié)合使用可監(jiān)控微服務(wù)服務(wù)的健康狀況,例如服務(wù)器內(nèi)存和磁盤空間使用情況、JVM 和內(nèi)存指標(biāo)、在線修改日志打印級別、請求鏈路響應(yīng)時間、服務(wù)上線或下線狀態(tài)變更通知等。
傳統(tǒng)接口文檔需開發(fā)人員根據(jù)接口規(guī)范編輯紙質(zhì)文檔。由于接口每次升級改造都需同步修改紙質(zhì)文檔,因此可能會出現(xiàn)多個版本文檔,也可能導(dǎo)致最新的文檔與實(shí)際接口不一致,所以給開發(fā)人員帶來額外的工作量。Swagger 是一個規(guī)范和完整的框架,用于生成、描述、調(diào)用和可視化 Restful 風(fēng)格的 Web 服務(wù)。Swagger 提供在線API 接口文檔,開發(fā)者可通過瀏覽器在線查看接口規(guī)范并且可在線單元測試。
在拆除省界收費(fèi)站的背景下,ETC 發(fā)行業(yè)務(wù)得到大力推廣,傳統(tǒng)辦理模式遠(yuǎn)遠(yuǎn)不能滿足當(dāng)前業(yè)務(wù)需求。本文通過對比單體架構(gòu)和微服務(wù)架構(gòu)優(yōu)缺點(diǎn),決定采用微服務(wù)架構(gòu)來設(shè)計并實(shí)現(xiàn)社會化發(fā)行系統(tǒng)。社會化發(fā)行系統(tǒng)采用前后端分離技術(shù)。前端使用VUE 框架實(shí)現(xiàn)H5頁面,為各商戶接入提供方便快捷的解決方案。微服務(wù)后臺采用SpringCloud 技術(shù)體系,其具備獨(dú)立開發(fā)部署、松耦合、彈性擴(kuò)張、高并發(fā)等特點(diǎn)。面對不同接入方需求,本系統(tǒng)即提供通用H5 頁面又提供REST 風(fēng)格微服務(wù)接口。因此不僅能快速響應(yīng)不同的需求,而且能適配需求的彈性擴(kuò)展。由于社會化發(fā)行系統(tǒng)并發(fā)能力以及擴(kuò)展能力增強(qiáng),可支持業(yè)務(wù)不斷增加、擴(kuò)展發(fā)行渠道。隨著本系統(tǒng)的上線部署,客戶可隨時隨地在不同渠道在線辦理ETC 發(fā)行業(yè)務(wù),不僅有效解決了網(wǎng)點(diǎn)少、距離遠(yuǎn)、排隊等待等問題,還大大提高了ETC 發(fā)行效率,在2019 年下半年發(fā)行430 萬套ETC 設(shè)備,高效完成遼寧省ETC 發(fā)行任務(wù)。