黃強文 曾丹
摘 要: 近年來,微服務(wù)架構(gòu)是當前最流行的分布式系統(tǒng)類型之一,相比傳統(tǒng)單體架構(gòu)它解決了數(shù)據(jù)、服務(wù)呈爆炸式增長帶來的沖擊問題。以構(gòu)建一個天氣預(yù)報分布式微服務(wù)系統(tǒng)為例,利用Spring Cloud框架將系統(tǒng)垂直切分為四個獨立的業(yè)務(wù)服務(wù):城市數(shù)據(jù)API微服務(wù)、天氣數(shù)據(jù)采集微服務(wù)、天氣數(shù)據(jù)API微服務(wù)和天氣預(yù)報微服務(wù)。系統(tǒng)集成Eureka做服務(wù)發(fā)現(xiàn),使用Zuul做路由網(wǎng)關(guān),結(jié)合Hystrix熔斷機制提高了系統(tǒng)的容錯性,并使用Docker容器快速獨立部署所有微服務(wù),實現(xiàn)了開發(fā)、測試、部署運維的一體化。
關(guān)鍵詞: 微服務(wù)架構(gòu); Spring Cloud框架; Docker容器
中圖分類號: TP309
文獻標志碼: A
文章編號:1007-757X(2019)06-0098-04
Abstract: In recent years, as one of the most popular distributed system types, the microservice architecture has solved the problem of explosive growth of data and services compared to the traditional singleton architecture. Taking the construction of a weather forecast distributed microservice system as an example, this paper uses the Spring Cloud framework to divide the system vertically into four separate business services: the city data API microservice, the weather data collection microservice, the weather data API microservice, and the weather forecast microservice. The system integrates Eureka for service discovering, uses Zuul as a routing gateway, improves the fault tolerance of the system in conjunction with the Hystrix zapping mechanism, and uses the Docker container to quickly and independently deploy all services, it realizes the integration of development, tests, deployment operation and maintenance.
Key words: Microservice architecture; Spring Cloud framework; Docker container
0?引言
隨著互聯(lián)網(wǎng)、云計算的高速發(fā)展,人們對數(shù)據(jù)信息化服務(wù)依賴程度越來越深。以往的單體應(yīng)用架構(gòu)和面向服務(wù)化應(yīng)用的架構(gòu)逐漸不能滿足業(yè)務(wù)的需求。而微服務(wù)這種分布式架構(gòu)的興起,是云計算應(yīng)用快速發(fā)展的必然產(chǎn)物,也將是未來整個軟件應(yīng)用架構(gòu)向著靈活多變、低耦合、高擴展性、動態(tài)伸縮發(fā)展的一個必然方向[1]。與此同時,Docker的誕生,代表著容器虛擬化技術(shù)的盛行高峰,它將極大減少微服務(wù)應(yīng)用實現(xiàn)大規(guī)模部署、落地的成本。
微服務(wù)架構(gòu)就是將單體應(yīng)用拆分為多個高內(nèi)聚低耦合的小型服務(wù),每個小服務(wù)運行在獨立進程,由不同的團隊開發(fā)和維護,服務(wù)間采用輕量級通信機制,獨立自動部署,可以采用不同的語言及存儲。微服務(wù)架構(gòu)具有如下優(yōu)勢[2]:
(1) 微服務(wù)架構(gòu)將業(yè)務(wù)系統(tǒng)徹底的組件化、服務(wù)化,微服務(wù)專注于業(yè)務(wù)邏輯,服務(wù)功
能簡單,邊界清晰,復(fù)雜度低,接口明確,服務(wù)利于開發(fā)、部署。
(2) 服務(wù)耦合度低,每個服務(wù)是一個微型的應(yīng)用,有完整的架構(gòu),可獨立部署。
(3) 微服務(wù)架構(gòu)允許根據(jù)服務(wù)的功能和團隊的自身條件選擇不同的技術(shù)路線。
(4) 優(yōu)良的容錯機制和熔斷機制,保障微服務(wù)之間交互的友好性。
本文將以一個天氣預(yù)報微服務(wù)系統(tǒng)為案例,使用Spring Cloud框架進行構(gòu)建,將系統(tǒng)拆分為四個獨立的子微服務(wù):城市數(shù)據(jù)API微服務(wù)、天氣數(shù)據(jù)采集微服務(wù)、天氣數(shù)據(jù)API微服務(wù)和天氣預(yù)報微服務(wù)。系統(tǒng)采用Eureka做服務(wù)注冊與發(fā)現(xiàn),Zuul做路由API網(wǎng)關(guān),F(xiàn)eign做服務(wù)節(jié)點間通信,Ribbon做負載均衡,Spring Cloud Config做統(tǒng)一管理微服務(wù)配置,Hystrix做服務(wù)熔斷,Turbine聚合監(jiān)控多個微服務(wù)運行狀態(tài),并使用Docker容器自動、快速、獨立部署所有微服務(wù)在一臺阿里云服務(wù)器上。本文最后給出天氣預(yù)報系統(tǒng)實現(xiàn)結(jié)果,并模擬天氣數(shù)據(jù)API微服務(wù)掉線操作驗證此系統(tǒng)優(yōu)良的容錯機制。
1?主要框架技術(shù)
1.1?Sping Cloud框架
Spring Cloud 是一系列框架、組件的有序集合,擁有功能完善的、輕量級的微服務(wù)實現(xiàn)組件,例如服務(wù)發(fā)現(xiàn)治理、服務(wù)容錯、服務(wù)網(wǎng)關(guān)、服務(wù)配置、負載均衡、消息總線、服務(wù)跟蹤等方面均有經(jīng)過實踐檢驗的成熟組件[2]。基于Spring Cloud 各組件的完整架構(gòu)圖,如圖1所示。
其中Eureka組件負責服務(wù)的注冊與發(fā)現(xiàn),很好將各服務(wù)連接起來。Zuul扮演API網(wǎng)關(guān)的角色,它對一切來自外部的服務(wù)請求進行路由轉(zhuǎn)發(fā)。Feign作為HTTP客戶端實現(xiàn)各微服務(wù)節(jié)點間的通信。Ribbon會根據(jù)服務(wù)網(wǎng)關(guān)的配置實現(xiàn)負載均衡。Config-Server組件為整個微服務(wù)系統(tǒng)提供了統(tǒng)一的配置管理中心。Hystrix起到監(jiān)控各個服務(wù)之間的通信調(diào)用情況,如果失敗次數(shù)達到一個設(shè)置的閾值將進行熔斷保護。Turbine 結(jié)合Dashboard組件是用來監(jiān)控查看Hystrix的熔斷情況,并且給予系統(tǒng)維護者一種圖形化的界面展示。
1.2?Docker容器
Docker是使用Google 公司推出的Go語言進行開發(fā)實現(xiàn)的高級容器引擎,其最終目的是實現(xiàn)對一個完整的應(yīng)用進行打包封裝、獨立部署并運行在宿主機上的管理,做到應(yīng)用組件級別的“一次封裝,隨處運行”[3]。從Docker實現(xiàn)方式的本質(zhì)上來講,它其實就是運行在宿主機上的一個進程。Docker通過namespace實現(xiàn)了資源隔離,通過cgroups實現(xiàn)了資源的限制,通過寫時復(fù)制機制實現(xiàn)了高效的文件操作[4]。
傳統(tǒng)的虛擬機技術(shù)一般都是虛擬出一套完整的硬件,在上面運行一個完整的操作系統(tǒng),然后把應(yīng)用程序部署運行在此虛擬操作系統(tǒng)上。和傳統(tǒng)的虛擬化方式相比,容器就十分輕便了。容器沒有虛擬出任何硬件,也沒有內(nèi)核,應(yīng)用程序都是運行在宿主機的內(nèi)核。Docker容器利用系統(tǒng)資源更高效,擁有著秒級的啟動速度、一致的運行環(huán)境、超方便的遷移和輕松的維護擴展特點。
Docker容器有3個基本概念:鏡像、容器和倉庫。
鏡像,其實是一個文件系統(tǒng),用來儲存容器運行時需要的程序資源、配置資源、庫資源等文件,它不包含任何動態(tài)數(shù)據(jù)。鏡像使用分層儲存,一層層進行構(gòu)建,后一層以前一層為基礎(chǔ),內(nèi)容一但構(gòu)建后就不會再改變了。
容器,是鏡像啟動的實例。容器其實就是一個進程,運行在一個完全獨立的隔離空間,有著自己的文件系統(tǒng)和網(wǎng)絡(luò)配置。所以容器封裝的應(yīng)用比直接在宿主運行更加安全。
倉庫,是一個用來儲存和分發(fā)鏡像的服務(wù)中心。類似Maven倉庫,1個倉庫包括多種標簽,1個標簽對應(yīng)著1個特定的鏡像。一般通過倉庫名:標簽的格式來確定某個應(yīng)用軟件具體的鏡像版本。
2?系統(tǒng)設(shè)計
本系統(tǒng)的業(yè)務(wù)主要拆分為四個獨立的子微服務(wù)。城市數(shù)據(jù)API微服務(wù)負責提供城市列表數(shù)據(jù),并提供接口給天氣數(shù)據(jù)采集微服務(wù)調(diào)用;天氣數(shù)據(jù)采集微服務(wù)負責請求第三方數(shù)據(jù)服務(wù)的天氣數(shù)據(jù),并保存在Redis緩存中;天氣數(shù)據(jù)API微服務(wù)負責調(diào)用天氣數(shù)據(jù)采集微服務(wù)緩存的天氣數(shù)據(jù),并提供接口給天氣預(yù)報微服務(wù)調(diào)用;天氣預(yù)報微服務(wù)面向用戶提供天氣查詢服務(wù)。此外,API網(wǎng)關(guān)負責路由轉(zhuǎn)發(fā)請求。整體架構(gòu)如圖2所示。
2.1?微服務(wù)功能設(shè)計
(1) 城市數(shù)據(jù)API微服務(wù):包含一張全國主要城市地區(qū)的Xml表,建立城市Javabean對象,然后利用JDK自帶的JAXB解析包,快速便捷將城市Xml表解析轉(zhuǎn)換為城市對象,并對外暴露接口/ cities,提供城市列表Json數(shù)據(jù)。
(2) 天氣數(shù)據(jù)采集微服務(wù):引入第三方Quartz定時器,集成Feign消費者客戶端遠程獲取城市數(shù)據(jù)API微服務(wù)提供的城市列表數(shù)據(jù),并結(jié)合配置了Httpclient的RestTemplate客戶端每隔半小時遠程調(diào)用第三方中國天氣數(shù)據(jù)網(wǎng)的Json格式天氣數(shù)據(jù),刷新并緩存到Redis節(jié)點中。
(3) 天氣數(shù)據(jù)API微服務(wù):根據(jù)城市Id號或者城市名稱從Redis緩存節(jié)點中獲取天氣數(shù)據(jù),因為Redis緩存的是Json格式數(shù)據(jù),所以用Jackson包把天氣數(shù)據(jù)轉(zhuǎn)換為Javabean,并對外暴露接口/weather/cityId/{cityId}和/weather/cityName/{cityName}。
(4) 天氣預(yù)報微服務(wù):暴露接口/report/cityId/{cityId},提供面向用戶請求服務(wù),把所有請求轉(zhuǎn)發(fā)到API網(wǎng)關(guān),并啟動Hystrix熔斷機制@FeignClient(name=" weather-gateway-zuul ", fallback=DataClientFallback.class)。
(5) 服務(wù)注冊中心:使用Eureka做服務(wù)注冊和發(fā)現(xiàn)中心,配置服務(wù)注冊中心的URL地址。一個微服務(wù)就是一個節(jié)點,是一個完整的應(yīng)用程序,并且可獨立運行部署。系統(tǒng)除了本文上述的四個主要業(yè)務(wù)相關(guān)的微服務(wù),還有API網(wǎng)關(guān)節(jié)點、配置中心Config-Server節(jié)點、Turbine的Hystrix監(jiān)控節(jié)點等。這些節(jié)點都是以Eureka客戶端形式注冊在Eureka服務(wù)端,然后各個節(jié)點間采用輕量級Feign組件就可以實現(xiàn)相互調(diào)用通信了。
(6) API網(wǎng)關(guān)服務(wù):根據(jù)URL轉(zhuǎn)發(fā)請求到不同的微服務(wù)。用戶請求訪問天氣預(yù)報微服務(wù)接口,天氣預(yù)報微服務(wù)統(tǒng)一向API網(wǎng)關(guān)微服務(wù)發(fā)送請求,API網(wǎng)關(guān)再把所有請求轉(zhuǎn)發(fā)到具體的其他微服務(wù)中,映射關(guān)系如下所示:
zuul.routes.city.path: /city/**
zuul.routes.city.serviceId: microservice-weather-city
zuul.routes.data.path: /data/**
zuul.routes.data.serviceId: microservice -weather-data
2.2?Docker容器部署設(shè)計
Spring Cloud應(yīng)用是在Sping Boot基礎(chǔ)上構(gòu)建的,而由Spring Boot開發(fā)的應(yīng)用內(nèi)嵌了Tomcat,所以一個Spring Cloud應(yīng)用可以直接以Jar包的形式獨立運行。利用Gradle把各個微服務(wù)項目分別打包成Jar包,并使用Docker的Dockerfile鏡像構(gòu)建命令把各Jar包制作成對應(yīng)鏡像。
Compose項目是Docker官方的開源項目,負責實現(xiàn)對Docker容器集群的快速編排。Compose通過一個模板文件docker-compose.yml來定義一系列相互有關(guān)聯(lián)的應(yīng)用容器為一個整體項目,并且可以為各應(yīng)用容器設(shè)置相應(yīng)的網(wǎng)絡(luò)環(huán)境和參數(shù)配置,如下所示為本系統(tǒng)的部分容器編排docker-compose.yml文件配置情況:
services://定義系統(tǒng)服務(wù)節(jié)點
discovery: //聲明服務(wù)注冊中心微服務(wù)節(jié)點
image: “discovery:0.0.1” // 配置discovery微服務(wù)容器鏡像
ports: “8761:8761” //映射主機的8761端口到discovery容器的8761端口
microservice-weather-city1: //聲明城市數(shù)據(jù)API微服務(wù)節(jié)點1
microservice-weather-city2: //聲明城市數(shù)據(jù)API微服務(wù)節(jié)點2,使用同一個鏡像,
//但通過設(shè)置不同端口來實現(xiàn),用作負載均衡作用,
//其它3個微服務(wù)節(jié)點也是一樣配置
microservice-weather-data: //聲明天氣數(shù)據(jù)API微服務(wù)節(jié)點
microservice -weather-collection //聲明天氣數(shù)據(jù)采集微服務(wù)節(jié)點
microservice-weather-report: //聲明天氣預(yù)報微服務(wù)節(jié)點
redis: //聲明redis緩存節(jié)點
weather-gateway-zuul: //聲明網(wǎng)關(guān)路由節(jié)點
…… //其它節(jié)點設(shè)置
networks: //設(shè)置所有容器節(jié)點在同一個網(wǎng)絡(luò)環(huán)境service_base_default中
default:
external:
name: “service_base_default”
3?系統(tǒng)實現(xiàn)
整個天氣預(yù)報微服務(wù)系統(tǒng)使用IntelliJ IDEA開發(fā),采用Java語言,基于Spring Boot創(chuàng)建應(yīng)用,并結(jié)合Gradle項目構(gòu)建工具編譯成可獨立運行的Jar包應(yīng)用。構(gòu)建出來的每個可獨立運行的Jar包應(yīng)用都是系統(tǒng)的節(jié)點,本系統(tǒng)實現(xiàn)的所有節(jié)點如表1所示。
本系統(tǒng)采用Docker容器快速編排所有節(jié)點,其中4個主要的微服務(wù)節(jié)點都啟動兩個實例以作負載均衡。系統(tǒng)運行在阿里云服務(wù)器上,不同節(jié)點采用不同的端口,其中天氣預(yù)報微服務(wù)microservice -weather-report提供面向用戶接
口/report/cityId/{cityId},供用戶查詢天氣數(shù)據(jù),用戶通過訪問http://39.108.184.144:8084/report/cityId/101020100可獲得上海近日的天氣預(yù)報,具體顯示界面如圖3所示,也可以通過該界面下拉列表選擇其他城市獲取對應(yīng)的天氣數(shù)據(jù)。
同時訪問Turbine聚合節(jié)點,可以監(jiān)控多個微服務(wù)運行狀態(tài),圖4顯示的是天氣預(yù)報微服務(wù)節(jié)點microservice-weather-report的運行指標,如每秒執(zhí)行的請求數(shù)、成功數(shù)、失敗數(shù)等。
此時,停止天氣數(shù)據(jù)API微服務(wù),再次查詢上海天氣預(yù)報情況,出現(xiàn)圖5所示界面,服務(wù)快速正常響應(yīng),并沒有崩潰,說明天氣預(yù)報微服務(wù)啟動了斷路器,并進入回退方法,響應(yīng)其他良好內(nèi)容“溫馨提示:天氣預(yù)報查詢服務(wù)暫不可用,請稍后再查詢哦!”給用戶,驗證了分布式微服務(wù)系統(tǒng)優(yōu)良的容錯機制。
4?總結(jié)
本文結(jié)合當前主流的分布式微服務(wù)架構(gòu)思想,將天氣預(yù)報系統(tǒng)切分為四個獨立的微服務(wù)節(jié)點,各微服務(wù)之間通過Eureka實現(xiàn)服務(wù)注冊與發(fā)現(xiàn),通過輕量級Feign做通信機制。系統(tǒng)引入Zuul做API網(wǎng)關(guān)轉(zhuǎn)發(fā)請求,Ribbon做負載均衡,Turbine做 Hystrix熔斷情況的監(jiān)控。同時,結(jié)合Docker實現(xiàn)微服務(wù)容器快速編排,并采取停止天氣數(shù)據(jù)API微服務(wù)操作驗證此系統(tǒng)優(yōu)良的容錯機制。使用當前最流行的Spring Cloud框架創(chuàng)建擴展性好、靈活、風(fēng)險低的微服務(wù)應(yīng)用[5],并結(jié)合Docker的秒級啟動,進程間隔離,快速部署的特點,無疑使得基于Spring Cloud和Docker的分布式微服務(wù)架構(gòu)將在未來軟件架中扮演舉足輕重的角色。
參考文獻
[1] 孫海洪. 微服務(wù)架構(gòu)和容器技術(shù)應(yīng)用[J].金融電子化,2016(5):63-64.
[2]?王方旭.基于Spring Cloud實現(xiàn)業(yè)務(wù)系統(tǒng)微服務(wù)化的設(shè)計與實現(xiàn)[J].電子技術(shù)與軟件工程,2018(8):60-61.
[3]?高禮,高昕.Docker技術(shù)在軟件開發(fā)過程中的應(yīng)用研究[J].軟件,2016,37(3):110-113.
[4]?馬雄. 基于微服務(wù)架構(gòu)的系統(tǒng)設(shè)計與開發(fā)[D].南京:南京郵電大學(xué),2017.
[5]?Marc Adler. Microservices Are the New Building Blocks of Financial Technology[J]. Wilmott,2017 (87):50-51.
(收稿日期: 2018.06.15)