魏東紅,王其才,商 超
(中國(guó)電子科技集團(tuán)公司 第五十四研究所,河北 石家莊 050000)
微服務(wù)架構(gòu)的概念由Martin和James在2014年正式提出,有別于傳統(tǒng)的單應(yīng)用服務(wù)架構(gòu)與SOA(Service-Oriented Architecture,面向服務(wù)架構(gòu))。單應(yīng)用架構(gòu)的所有業(yè)務(wù)邏輯及實(shí)現(xiàn)全部在一個(gè)工程中,開發(fā)方式簡(jiǎn)單,但耦合性強(qiáng),隨著系統(tǒng)的升級(jí),復(fù)雜度也越來越高,后期維護(hù)成本較大[1];SOA將系統(tǒng)的邏輯功能進(jìn)行服務(wù)化拆分,降低了服務(wù)之間的耦合性;微服務(wù)架構(gòu)是在SOA的基礎(chǔ)上逐漸發(fā)展而來,將系統(tǒng)的邏輯功能進(jìn)一步細(xì)化拆分,變?yōu)槎鄠€(gè)高內(nèi)聚、低耦合的微型服務(wù),可由不同的團(tuán)隊(duì)、不同的編程語言、不同的設(shè)計(jì)模式、不同的存儲(chǔ)數(shù)據(jù)庫開發(fā)和維護(hù),每個(gè)微服務(wù)使用獨(dú)立的進(jìn)程進(jìn)行部署[2],微服務(wù)之間采用輕量級(jí)的通信機(jī)制進(jìn)行數(shù)據(jù)交互。相比SOA,微服務(wù)的分解粒度更細(xì)、通信機(jī)制輕量化、開發(fā)迭代速度快、服務(wù)測(cè)試可實(shí)現(xiàn)自動(dòng)化[3]。
微服務(wù)架構(gòu)一般分為注冊(cè)中心、微服務(wù)(含網(wǎng)關(guān))、數(shù)據(jù)庫等,如圖1所示。
圖1 微服務(wù)架構(gòu)
鑒于目前存在的服務(wù)功能劃分不清晰問題,本文探討一種通用的Web系統(tǒng)設(shè)計(jì)架構(gòu),將微服務(wù)架構(gòu)細(xì)化分解,能夠滿足大多數(shù)使用場(chǎng)景,如圖2所示。
圖2 Web系統(tǒng)架構(gòu)設(shè)計(jì)
Web系統(tǒng)架構(gòu)主要分為注冊(cè)中心、網(wǎng)關(guān)、登錄認(rèn)證、反向代理、消息中間件、各類功能性微服務(wù),貫穿服務(wù)訪問全流程,微服務(wù)、注冊(cè)中心、代理等均可以Docker容器的方式快速發(fā)布部署與啟動(dòng)[4]。
微服務(wù)通過注冊(cè)中心有機(jī)結(jié)合在一起,未使用注冊(cè)中心時(shí),需要將調(diào)用系統(tǒng)的地址寫入配置中,以便調(diào)用系統(tǒng)提供的服務(wù)接口。微服務(wù)啟動(dòng)時(shí),向注冊(cè)中心注冊(cè),注冊(cè)中心會(huì)維護(hù)微服務(wù)的健康狀態(tài)以及調(diào)用信息,接口調(diào)用時(shí),系統(tǒng)無需事先知道對(duì)方的地址和端口等信息,通過與注冊(cè)中心的交互,可獲取對(duì)方微服務(wù)的信息,進(jìn)行接口的調(diào)用,例如Spring Cloud中的Feign接口,只需配置對(duì)應(yīng)的服務(wù)名即可。常用的注冊(cè)中心有Zookeeper,Consul,Eureka,Nacos等。
反向代理將瀏覽器端的請(qǐng)求映射至對(duì)應(yīng)的微服務(wù)或靜態(tài)文件,獲取前端靜態(tài)文件(HTML,JS,CSS等)、通過Ajax交互數(shù)據(jù)、連接認(rèn)證服務(wù)器均可通過代理進(jìn)行地址映射,一般的軟件設(shè)計(jì)中,采用Nginx代理。Nginx實(shí)現(xiàn)了負(fù)載均衡,在服務(wù)集群部署的情況下,多個(gè)微服務(wù)可分擔(dān)負(fù)載,避免因?yàn)槟硞€(gè)服務(wù)下線引起系統(tǒng)崩潰。
服務(wù)網(wǎng)關(guān)對(duì)Web瀏覽器的請(qǐng)求進(jìn)行統(tǒng)一轉(zhuǎn)發(fā),將瀏覽器端的請(qǐng)求和后臺(tái)微服務(wù)群體隔離,同時(shí)集成認(rèn)證服務(wù)的配置,實(shí)現(xiàn)用戶鑒權(quán),未通過認(rèn)證的請(qǐng)求重定向至登錄界面,用戶登錄后,網(wǎng)關(guān)對(duì)瀏覽器請(qǐng)求進(jìn)行轉(zhuǎn)發(fā),并將數(shù)據(jù)返回至瀏覽器呈現(xiàn)。鑒于服務(wù)網(wǎng)關(guān)的統(tǒng)一轉(zhuǎn)發(fā)功能,可記錄用戶的操作日志,便于分析用戶行為,監(jiān)控請(qǐng)求及服務(wù)的運(yùn)行情況,對(duì)客戶端請(qǐng)求進(jìn)行熔斷和限流處理等。常用的服務(wù)網(wǎng)關(guān)有Spring Cloud Gateway,Kong,Dubbo Proxy等。
Web管理系統(tǒng)通常進(jìn)行登錄認(rèn)證,網(wǎng)關(guān)登錄認(rèn)證可采用外部的認(rèn)證服務(wù),也可單獨(dú)實(shí)現(xiàn),由于系統(tǒng)中可能存在多個(gè)微服務(wù)具備管理頁面,因此需要實(shí)現(xiàn)單點(diǎn)登錄(SingleSignOn,SSO)功能,用戶登錄系統(tǒng)后,可獲得整個(gè)系統(tǒng)相關(guān)服務(wù)的訪問權(quán)限,訪問互相信任的服務(wù)頁面,無需二次登錄,提升用戶體驗(yàn)。登錄認(rèn)證可與網(wǎng)關(guān)相配合,常用的認(rèn)證服務(wù)協(xié)議有CAS,OAuth2,WebAuth等。
消息中間件實(shí)現(xiàn)了微服務(wù)之間的解耦,同時(shí)滿足應(yīng)用服務(wù)的擴(kuò)展需求,微服務(wù)之間可通過消息機(jī)制進(jìn)行通信,服務(wù)發(fā)布者可直接將消息發(fā)送給消息中間件,無需等待處理消息的服務(wù)是否啟動(dòng),且支持多個(gè)消息的消費(fèi)者,減少了繁雜的、相似的代碼,隨后消息中間件將消息存放在若干隊(duì)列中,消息的消費(fèi)者讀取消息隊(duì)列后,對(duì)關(guān)注消息進(jìn)行處理,目前常用的消息中間件有Activemq,Rabbitmq等。
事件通知類微服務(wù)主要負(fù)責(zé)監(jiān)聽寫入消息中間件的事件,將事件轉(zhuǎn)化為數(shù)據(jù)處理的通知(包括對(duì)數(shù)據(jù)進(jìn)行處理、前端數(shù)據(jù)的推送呈現(xiàn)等),然后在消息中間件中發(fā)布消息主題與內(nèi)容,訂閱該主題的微服務(wù)可獲取消息內(nèi)容進(jìn)行處理,這樣做可以將事件產(chǎn)生與處理徹底解耦,方便數(shù)據(jù)處理方式的改進(jìn)和替換。
頁面類微服務(wù)主要包括頁面相關(guān)的靜態(tài)文件和數(shù)據(jù)推送相關(guān)服務(wù),目前Nodejs,Webpack,Npm,Spring Boot等工具均能很好地實(shí)現(xiàn)前端服務(wù)的獨(dú)立開發(fā),當(dāng)前比較流行的前端開發(fā)框架有Vue,Angular,React等[5],這些框架的出現(xiàn)使得開發(fā)更為便捷,易于實(shí)現(xiàn)前后端服務(wù)的分離。前后臺(tái)分離能夠使團(tuán)隊(duì)更加專注于前端或后端的開發(fā),工作職責(zé)更加明確,有助于提升團(tuán)隊(duì)技術(shù)水平和研發(fā)能力。
數(shù)據(jù)處理類微服務(wù)主要負(fù)責(zé)系統(tǒng)的復(fù)雜數(shù)據(jù)處理,包含數(shù)據(jù)整合、算法、視圖模型等。由于該類微服務(wù)需要經(jīng)常進(jìn)行復(fù)雜處理和計(jì)算,占用的資源較其他微服務(wù)多,因此需要部署在性能較高的節(jié)點(diǎn),此類微服務(wù)是系統(tǒng)的核心,保證服務(wù)的穩(wěn)定性、可靠性尤為重要,通常通過集群部署和負(fù)載均衡配置,緩解該類服務(wù)的運(yùn)行壓力。
數(shù)據(jù)訪問類微服務(wù)主要負(fù)責(zé)數(shù)據(jù)庫的持久化操作,進(jìn)行數(shù)據(jù)存儲(chǔ)、獲取、簡(jiǎn)單統(tǒng)計(jì)等操作。該類服務(wù)直接面向數(shù)據(jù)庫,可配置Hibernate,MyBatis,Spring JPA等持久化工具,簡(jiǎn)化程序,其接收其他微服務(wù)的數(shù)據(jù)訪問請(qǐng)求,能夠進(jìn)行數(shù)據(jù)模型轉(zhuǎn)換、存儲(chǔ)數(shù)據(jù)和返回微服務(wù)所需的數(shù)據(jù)。
接口適配類微服務(wù)主要負(fù)責(zé)處理與外部系統(tǒng)或設(shè)施的接口,每個(gè)服務(wù)可進(jìn)行單獨(dú)配置,由于系統(tǒng)接口多種多樣,數(shù)據(jù)也千差萬別,因此接口適配類微服務(wù)數(shù)量繁多,對(duì)同一類別的數(shù)據(jù),如何統(tǒng)一數(shù)據(jù)模型是降低系統(tǒng)復(fù)雜度的關(guān)鍵因素,接口適配一般為雙向服務(wù):(1)通過接口獲取數(shù)據(jù)之后進(jìn)行簡(jiǎn)單處理,然后將數(shù)據(jù)發(fā)送至數(shù)據(jù)處理類微服務(wù)或數(shù)據(jù)訪問類微服務(wù)。(2)接收內(nèi)部微服務(wù)的數(shù)據(jù),將數(shù)據(jù)處理為外部系統(tǒng)所需格式,并通過接口進(jìn)行數(shù)據(jù)發(fā)送。
下面以停車場(chǎng)監(jiān)控為例,說明基于微服務(wù)的Web系統(tǒng)設(shè)計(jì)架構(gòu)實(shí)現(xiàn)方式,系統(tǒng)架構(gòu)如圖3所示。
圖3 停車場(chǎng)監(jiān)控微服務(wù)架構(gòu)
監(jiān)視流程如下:
(1)用戶在客戶端訪問停車場(chǎng)監(jiān)控系統(tǒng)界面,訪問請(qǐng)求通過Nginx代理至服務(wù)網(wǎng)關(guān),服務(wù)網(wǎng)關(guān)通過約定的請(qǐng)求消息頭判斷用戶是否已經(jīng)登錄,若未登錄,則將請(qǐng)求重定向至認(rèn)證服務(wù)提供的統(tǒng)一登錄界面,并帶有源請(qǐng)求路徑信息。
(2)用戶輸入登錄名和密碼,并成功登錄,頁面隨機(jī)跳轉(zhuǎn)至停車場(chǎng)車位監(jiān)控頁面。
(3)停車場(chǎng)車位監(jiān)控頁面發(fā)送請(qǐng)求獲取停車位和停車位占用信息,服務(wù)網(wǎng)關(guān)將請(qǐng)求轉(zhuǎn)發(fā)至數(shù)據(jù)處理服務(wù),數(shù)據(jù)處理服務(wù)調(diào)用數(shù)據(jù)訪問服務(wù)接口從數(shù)據(jù)庫獲取數(shù)據(jù),通過一定的方式處理后,將數(shù)據(jù)視圖返回至監(jiān)控界面,在前端生成各類視圖。
(4)點(diǎn)開停車場(chǎng)的視頻控制管理界面,由于用戶已經(jīng)登錄系統(tǒng),獲得了相關(guān)系統(tǒng)的授權(quán)信息,可以直接訪問視頻控制界面,對(duì)視頻設(shè)備進(jìn)行控制,無需二次登錄。
(5)當(dāng)停車情況發(fā)生改變時(shí),例如車輛駛?cè)牖螂x開停車位,傳感器適配微服務(wù)接收傳感器的變化數(shù)據(jù),判斷變化內(nèi)容,根據(jù)變化內(nèi)容生成事件,存入消息中間件,同時(shí)調(diào)用數(shù)據(jù)訪問微服務(wù)將變化內(nèi)容存入數(shù)據(jù)庫中。事件通知微服務(wù)監(jiān)聽事件的發(fā)生,生成頁面推送更新消息;Web微服務(wù)監(jiān)聽頁面更新消息并將更新推送至前端監(jiān)控頁面,頁面經(jīng)過數(shù)據(jù)處理后顯示變化信息。
(6)用戶退出系統(tǒng)后,之前的登錄信息在認(rèn)證服務(wù)注銷,此時(shí)監(jiān)控頁面、監(jiān)控錄像均不可查看。
目前微服務(wù)架構(gòu)還存在多種待優(yōu)化問題,本文通過將統(tǒng)一認(rèn)證服務(wù)納入Web系統(tǒng)架構(gòu),實(shí)現(xiàn)系統(tǒng)的單點(diǎn)登錄功能,避免用戶二次登錄,將微服務(wù)按照功能分為服務(wù)網(wǎng)關(guān)、事件通知、數(shù)據(jù)處理、數(shù)據(jù)訪問、接口適配,各類服務(wù)職責(zé)明確,邊界清晰,有利于進(jìn)行微服務(wù)的設(shè)計(jì)。微服務(wù)之間通過消息中間件的方式實(shí)現(xiàn)服務(wù)之間異步交互,使服務(wù)之間進(jìn)一步解耦,并以停車場(chǎng)監(jiān)控系統(tǒng)為例,對(duì)系統(tǒng)架構(gòu)進(jìn)行解釋說明,為進(jìn)行Web系統(tǒng)的開發(fā)提供了一種架構(gòu)設(shè)計(jì)方案。