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