本博文主要向大家介紹如何使用Spring Cloud和Docker構建微服務平臺。
什么是Spring Cloud?
Spring Cloud 是Pivotal提供的用于簡化分布式系統(tǒng)構建的工具集刁愿。Spring Cloud引入了云平臺連接器(Cloud Connector)和服務連接器(Service Connector)的概念。云平臺連接器是一個接口者春,需要由云平臺提供者進行實現(xiàn)纫骑,以便庫中的其他模塊可以與該云平臺協(xié)同工作冠王。
Spring Boot
Spring Cloud最重要的一點是它可以和Spring Boot一起工作,Spring Boot可以幫助開發(fā)者更容易地創(chuàng)建基于Spring的應用程序和服務蝌以。
從Spring Boot項目名稱中的Boot就可以看出來,Spring Boot的作用在于創(chuàng)建和啟動新的基于Spring框架的項目何之。Spring Boot會選擇最適合的Spring子項目和第三方開源庫進行整合跟畅。大部分Spring Boot應用只需要非常少的配置就可以快速運行起來。Spring Boot包含的特性如下:
創(chuàng)建可以獨立運行的Spring應用溶推。
- 直接嵌入Tomcat或Jetty服務器徊件,不需要部署WAR文件。
- 提供推薦的基礎POM文件來簡化Apache Maven配置蒜危。
- 盡可能的根據(jù)項目依賴來自動配置Spring框架虱痕。
- 提供可以直接在生產(chǎn)環(huán)境中使用的功能,如性能指標辐赞、應用信息和應用健康檢查部翘。
- 沒有代碼生成,也沒有XML配置文件响委。
服務發(fā)現(xiàn)和智能路由
每一個服務都含有一個特定意義的微服務架構新思。當你在Spring Cloud上構建微服務架構時,這里有幾個基本概念需要首先澄清下晃酒。首先表牢,你需要要先創(chuàng)建Configuration Service和Discovery Service兩個基礎服務。如下圖所示:
- 上面的圖片說明了四個微服務以及各個服務之間的依賴關系贝次。
- Configuration service處于最頂端崔兴,黃色標識,而且被其它微服務所依賴蛔翅。
- Discovery service處于最低端敲茄,藍色標識,同時也被其它服務所依賴山析。
- 綠色標識的兩個微服務是我們本系列博文中用到的兩個應用案例:電影和觀影建議堰燎。
Configuration Service
Configuration Service在微服務架構中是一個非常重要的組件。如12要素應用理論所說笋轨, 微服務應用的配置應該存儲在環(huán)境中秆剪,而不是本地項目中赊淑。
Configuration service(配置服務)是一個必不可少的基礎組件的原因是因為它可以對所有通過點對點和檢索的基礎服務進行服務管理。
假設我們有多個部署環(huán)境仅讽。比如我們有一個臨時環(huán)境和一個生產(chǎn)環(huán)境陶缺,針對每個環(huán)境的配置將會是不同的。每一個configuration service 將會由一個獨立的Git倉庫來存放環(huán)境配置洁灵。沒有其它環(huán)境能夠訪問到這個配置倉庫饱岸,它只是提供該環(huán)境中運行的配置服務罷了。
當Configuration service啟動后徽千,它將會指向那些根據(jù)配置文件配置的路徑并啟動對應服務苫费。每一個微服務通過讀取自己配置文件中的具體環(huán)境來運行。在這一過程中双抽,配置是通過版本管理來進行的內(nèi)部和集中化管理百框,更改配置不需要重啟服務。
通過Spring Cloud提供的服務終端荠诬,你可以更改環(huán)境配置琅翻,并向Discovery service(發(fā)現(xiàn)服務)發(fā)送一個刷新信號,所有的用戶都會收到新的配置通知柑贞。
Discovery Service
Discovery Service(發(fā)現(xiàn)服務)是另一個重要的微服務架構的組件方椎。
Discovery Service管理運行在容器中的眾多服務實例,而這些實例工作在集群環(huán)境下钧嘶。在這些應用中棠众,我們使用客戶端的方式稱之為從服務到服務。舉個例子有决,我使用Spring Cloud Feign 闸拿,這是一個基于Restful風格的微服務提供的客戶端開源項目,它是從Netflix OSS project項目中派生出來的书幕。
@FeignClient("movie")
public interface MovieClient {
@RequestMapping(method = RequestMethod.GET, value = "/movies")
PagedResources findAll();
@RequestMapping(method = RequestMethod.GET, value = "/movies/{id}")
Movie findById(@RequestParam("id") String id);
@RequestMapping(method = RequestMethod.POST, value = "/movies", produces = MediaType.APPLICATION_JSON_VALUE)
void createMovie(@RequestBody Movie movie);
}
在上面的例子中新荤,我創(chuàng)建了一個Feign 客戶端,并映射了一個REST API方法來暴露電影服務台汇。使用@FeignClient注解苛骨,可以聲明我想要為movie微服務而創(chuàng)建的客戶端API。接下來我聲明了一個我想要實現(xiàn)的服務映射苟呐。通過在方法上聲明一個URL規(guī)則來描述一個REST API的路由規(guī)則痒芝。
更令人興奮的是,這一切在Spring Cloud中都很容易牵素,我所要做的僅僅是知道service ID來創(chuàng)建我的Feign 客戶端严衬。服務的URL地址在運行時環(huán)境是自動配置的,因為每一個在集群中的微服務將會在啟動時通過綁定serviceid的方式來進行注冊笆呆。
微服務架構中的其它服務请琳,也是通過上面提到的方式運行粱挡。我只需要知道進行通訊服務的serviceid,所有的操作都是通過Spring自動綁定的单起。
API Gateway
API Gateway 服務是Spring Cloud的另一個重要組件抱怔。它可以用來管理集群服務中的領域實體劣坊。下圖的綠色六邊形是我們提供的數(shù)據(jù)驅動服務嘀倒,主要用來管理自己的實體類和數(shù)據(jù)庫。通過添加API Gateway服務局冰,我們可以為通過下面綠顏色的服務為每一個API路由創(chuàng)建一個代理暴露接口测蘑。
假設推薦服務和電影服務都暴露他們自己的REST API在自己管理的域實體上。API gataway通過discovery service和從其它服務注入的基于代理路由的 API方法康二。通過這種方式碳胳,包括推薦服務和電影服務將擁有一個完整定義的路由,通過暴露的REST API獲得本地的微服務沫勿。API Gateway將會重定義路由請求到服務實例挨约,這些請求都是基于HTTP的刻帚。
示例項目
我已經(jīng)在GitHub上創(chuàng)建了一個實例項目:demo临扮,這個項目是一個端到端的原生云平臺,使用Spring Cloud構建實際的微服務架構桩了。
基本概念
- 使用Docker進行集成測試
- 混合持久化
- 微服務架構
- 服務發(fā)現(xiàn)
- API網(wǎng)關
Docker
使用Docker對每一個服務進行構建和部署蔓挖。使用Docker Compose在一個開發(fā)機上進行端到端的集成測試夕土。
混合持久化
混合持久化其實就是說使用多種數(shù)據(jù)庫來存儲。不同的微服務實例都會使用它們自己的數(shù)據(jù)庫瘟判,并通過REST服務或者消息總線來通信怨绣,舉個例子,你可以使用基于以下數(shù)據(jù)庫來構建微服務:
- Neo4j(圖形化)
- MongoDB(文檔化)
- MySQL(關聯(lián))
微服務架構
這個例子演示了如何使用微服務創(chuàng)建一個新的應用拷获。由于在項目中的每一個微服務只有一個單一的父項目篮撑。開發(fā)者為此得到的收益是可以在本機上運行和開發(fā)每一個微服務。添加一個新的微服務非常簡單匆瓜,當發(fā)現(xiàn)微服務時將會自動發(fā)現(xiàn)運行時的集群環(huán)境上赢笨。
Service Discovery
項目中包含兩個發(fā)現(xiàn)服務,一個在Netflix Eureka陕壹,另一個使用了
Consul from Hashicorp质欲。多種發(fā)現(xiàn)服務提供了多種選擇,一個是使用(Consul)來做DNS服務集群糠馆,另一個是(Consul)基于代理的API 網(wǎng)關嘶伟。
API 網(wǎng)關
每一個微服務都關聯(lián)Eureka,在整個集群中檢索API路由又碌。使用這個策略九昧,每一個在集群上運行的微服務只需要通過一個共同的API網(wǎng)關進行負載均衡和暴露接口绊袋,每一個服務也會自動發(fā)現(xiàn)并將路由請求轉發(fā)到自己的路由服務中。這個代理技術有助于開發(fā)用戶界面铸鹰,作為平臺完整的 API通過自己的主機映射為代理服務癌别。
Docker 實例
下面的實例將會通過Maven來構建,使用Docker為每一個微服務構建容器鏡像蹋笼。我們可以很優(yōu)雅的使用Docker Compose在我們自己的主機上搭建全部的微服務集群展姐。
開始構建
在這之前,請先移步至項目的GitHub 倉庫剖毯。
github
克隆或者fork這個項目并且把源碼下載到自己的電腦上圾笨。下載完畢后,你需要使用Maven和Docker來編譯和構建本地的容器鏡像逊谋。
下載Docker
首先擂达,如果你還沒有Docker請先下載它〗鹤蹋可以跟隨這個指南來獲取Docker板鬓,然后在開發(fā)機上安裝并運行。
當然你也需要安裝Docker Compose究恤,這個指南將會幫到你:docs俭令。
環(huán)境要求
能夠運行實例程序,需要在你的開發(fā)機上安裝下面的軟件:
- Maven 3
- Java 8
- Docker
- Docker Compose
構建項目
通過命令行方式來構建當前項目丁溅,在項目的根目錄中運行如下的命令:
$ mvn clean install
項目將會根據(jù)pom.xml中的每一個項目聲明中下載相應的依賴jar包唤蔗。每一個服務都將會被構建,同時Maven的Docker插件將會自動從本地Docker Registry中構建每一個容器鏡像窟赏。Docker將會在構建成功后妓柜,根據(jù)命令行運行mvn clean install來清除相應的資源。
通過Docker compose 啟動集群
現(xiàn)在每一個鏡像都成功構建完畢涯穷,我們使用Docker Compose來加速啟動我們的集群棍掐。我已經(jīng)將Docker Compose的yaml文件包含進了項目中,大家可以從GitHub上獲取拷况。
現(xiàn)在我們通過下面的命令行啟動微服務集群:
$ docker-compose up
如果一切配置都是正確的作煌,每一個容器鏡像將會通過在Docker上的虛擬容器和自動發(fā)現(xiàn)的網(wǎng)絡服務來運行。當他們開始順序啟動時赚瘦,你將會看到一系列的日志輸出粟誓。這可能需要一段時間來完成,取決于運行你實例程序的機器性能起意。
一旦容器啟動成功鹰服,你將會通過Eureka主機看到通過Discovery service注冊上來的應用服務。
通過命令行終端復制粘貼下面的命令到Docker中定義的$DOCKER_HOST環(huán)境變量中。
$ open $(echo \"$(echo $DOCKER_HOST)\"|
\sed 's/tcp:\/\//http:\/\//g'|
\sed 's/[0-9]\{4,\}/8761/g'|
\sed 's/\"http://g')
如果Eureka正確的啟動悲酷,瀏覽器將會啟動并打開Eureka服務的儀表盤套菜,如下圖所示:
我們將會看到每一個正在運行的服務實例和狀態(tài)。通過下面的命令來獲取數(shù)據(jù)驅動服務设易,例如 movie 服務逗柴。
$ open $(echo \"$(echo $DOCKER_HOST)/movie\"|
\sed 's/tcp:\/\//http:\/\//g'|
\sed 's/[0-9]\{4,\}/10000/g'|
\sed 's/\"http://g')
這個命令將會訪問根據(jù)導航網(wǎng)關終端提供的代理方式訪問movie服務的REST API終端。這些REST API使用 HATEOAS 來配置顿肺,它是一個通過內(nèi)嵌鏈接的方式支持自動發(fā)現(xiàn)服務的接口戏溺。
{
"_links" : {
"self" : {
"href" : "http://192.168.59.103:10000/movie"
},
"resume" : {
"href" : "http://192.168.59.103:10000/movie/resume"
},
"pause" : {
"href" : "http://192.168.59.103:10000/movie/pause"
},
"restart" : {
"href" : "http://192.168.59.103:10000/movie/restart"
},
"metrics" : {
"href" : "http://192.168.59.103:10000/movie/metrics"
},
"env" : [ {
"href" : "http://192.168.59.103:10000/movie/env"
}, {
"href" : "http://192.168.59.103:10000/movie/env"
}],
"archaius" : {
"href" : "http://192.168.59.103:10000/movie/archaius"
},
"beans" : {
"href" : "http://192.168.59.103:10000/movie/beans"
},
"configprops" : {
"href" : "http://192.168.59.103:10000/movie/configprops"
},
"trace" : {
"href" : "http://192.168.59.103:10000/movie/trace"
},
"info" : {
"href" : "http://192.168.59.103:10000/movie/info"
},
"health" : {
"href" : "http://192.168.59.103:10000/movie/health"
},
"hystrix.stream" : {
"href" : "http://192.168.59.103:10000/movie/hystrix.stream"
},
"routes" : {
"href" : "http://192.168.59.103:10000/movie/routes"
},
"dump" : {
"href" : "http://192.168.59.103:10000/movie/dump"
},
"refresh" : {
"href" : "http://192.168.59.103:10000/movie/refresh"
},
"mappings" : {
"href" : "http://192.168.59.103:10000/movie/mappings"
},
"autoconfig" : {
"href" : "http://192.168.59.103:10000/movie/autoconfig"
}
}
}
總結
這是使用Spring Cloud和Docker構建微服務架構的系列博文的第一部分。
在本文中挟冠,我們接觸到了如下的概念:
- Service Discovery
- Externalized Configuration
- API Gateway
- Service Orchestration with Docker Compose
在這之后的博文中于购,我們將會演示如何使用后臺服務來構建前端應用程序,同時也會介紹一個混合性持久化的實例知染,使用MySQL和Neo4j。
原文鏈接:http://www.dockone.io/article/510