這是系列博文中的第一篇,本文做者使用Spring Cloud和docker構建微服務平臺,文章的例子淺顯易懂,但願瞭解微平臺構建的同窗可以從這裏會收穫良多.
這篇系列博文主要向你們介紹如何使用Spring Cloud和Docker構建微服務平臺。 html
Spring Cloud 是一個 pivotal提供的用於進行分佈式系統構建時提供一些經常使用的解決方案的工具集。若是你對使用 Spring Framework構建應用程序很熟悉的話,Spring Cloud 提供了一些經常使用基礎組件的構建服務。
在Spring Cloud 提供的解決方案中,你將會發現以下的問題: 前端
關於Spring Cloud 最重要的部分就是啓動Spring Boot的概念模型上。
對於那些剛使用Spring Boot的人而言,他所要作的僅僅是起一個名副其實的項目名,你就會構建一個使用Spring Framework開發的微系統項目,能夠直接轉換成使用最小配置,萬事俱備的完美的系統應用了。 git
每個服務都含有一個特定意義的微服務架構。當你在Spring Cloud上構建微服務架構時,這裏有幾個基本概念須要首先澄清下。首先,你要先建立Configuration Service和Discovery Service 兩個基礎服務。以下圖所示: github
上面的圖片說明了四個微服務以及各個服務之間的依賴關係。
configuration service 處於最頂端,黃色標識,並且被其餘微服務所依賴。
discovery service 處於最低端,藍色標識,同時也被其餘服務所依賴。
綠色標識的兩個微服務只是一個本地實例應用的一部分,下面我將會使用他們建立博客,分別是:電影和觀影建議。
Configuration Service
Configuration Service 在微服務架構中是一個很是重要的組件。基於在 twelve-factor app上構建的應用,配置你的微服務應用在環境中而不是在本地項目中。
configuration service 是一個必不可少的基礎組件的緣由是由於它能夠對全部經過點對點和檢索的基礎服務進行服務管理。他的優點在於多用途。
假設咱們有多個部署環境。好比咱們有一個臨時環境和一個生產環境,針對每一個環境的配置將會是不一樣的。每個 configuration service 將會由一個獨立的Git倉庫來存放環境配置。沒有其餘環境可以訪問到這個配置倉庫,它只是提供該環境中運行的配置服務罷了。 spring
當configuration service 啓動後,它將會指向那些根據配置文件配置的路徑並啓動對應服務。每個微服務經過讀取本身配置文件中的具體環境來運行。在這一過程當中,配置是經過版本管理來進行的內部和集中化管理,更改配置不須要重啓服務。
經過Spring Cloud提供的服務終端,你能夠更改環境配置同時向discovery service 發送一個刷新信號,全部的用戶都會收到新的配置通知。
Discovery Service
Discovery Service 是另外一個重要的微服務架構的組件.Discovery Service管理運行在容器中的衆多服務實例,而這些實例工做在集羣環境下.在這些應用中,咱們使用客戶端的方式稱之爲從服務到服務.舉個例子,我使用 Spring Cloud Feign ,這是一個基於RESTFUL風格的微服務提供的客戶端開源項目,它是從 Netflix OSS project項目中派生出來的。 docker
1 @FeignClient("movie") 2 public interface MovieClient { 3 @RequestMapping(method = RequestMethod.GET, value = "/movies") 4 PagedResources findAll(); 5 6 @RequestMapping(method = RequestMethod.GET, value = "/movies/{id}") 7 Movie findById(@RequestParam("id") String id); 8 9 @RequestMapping(method = RequestMethod.POST, value = "/movies", 10 produces = MediaType.APPLICATION_JSON_VALUE) 11 void createMovie(@RequestBody Movie movie); 12 }
在上面的例子中,我建立了一個Feign客戶端 映射了一個REST API方法來暴露個人電影服務.使用@FeignClient註解,我聲明瞭我想要爲movie微服務而建立的客戶端API.接下來我聲明瞭一個我想要實 現的服務映射.經過在方法上聲明一個URL規則來描述一個REST API的路由規則。
使人興奮的是,這一切在Spring Cloud都很容易,我所要作的僅僅是知道service ID 來建立個人Feign 客戶端.服務的URL地址在運行時環境是自動配置的,由於每個在集羣中的微服務將會在啓動時經過綁定serviceid的方式來進行註冊。
我微服務架構中的其餘服務,也是經過上面提到的方式運行。我只須要知道進行通信服務的serviceid,全部的操做都是經過Spring自動綁定的。
API Gateway
API Gateway 服務是Spring Cloud的另外一個重要組件.它主要用來建立服務集羣並管理本身域名下的應用實例.下圖的綠色六邊形是咱們提供的數據驅動服務,主要用來管理本身域名下的 實體類和數據庫.經過添加 API Gateway 服務,咱們能夠爲經過下面綠顏色的服務爲每個API路由建立一個代理暴露接口。 shell
讓咱們假設推薦服務和電影服務都暴露他們本身的REST API在本身管理的域實體上.API gataway經過discovery service和從其餘服務注入的基於代理路由的 API方法.經過這種方式,包括推薦服務和電影服務將擁有一個完整定義的路由,經過暴露的REST API得到本地的微服務.API Gateway 將會重定義路由請求到服務實例,這些請求是經過HTTP請求的方式擁有。 數據庫
我已經在github上建立了一個實例項目,這個項目是一個端到端的原生雲平臺,使用Spring Cloud 構建實際的微服務架構。
基本概念: api
使用Docker對每個服務進行構建和部署。使用Docker compose在一個開發機上進行端到端的集成測試。 瀏覽器
實例程序中的一個核心概念是如何將混合持久化轉化爲實際.項目中的微服務使用本身的數據庫同時集成經過REST或者消息總線方式從其餘的服務提供的數據接入。舉個例子,你能夠擁有從如下數據庫中提供的微服務:
這個例子演示瞭如何使用微服務建立一個新的應用,而不是單體應用優先策略。因爲在項目中的每個微服務只有一個單一的父項目。開發者爲此獲得的收益是能夠在本機上運行和開發每個微服務。添加一個新的微服務很是簡單,當發現微服務時將會自動發現運行時的集羣環境上。
項目中包含兩個發現服務,一個在 Netflix Eureka,另外一個使用了
Consul from Hashicorp。多種發現服務提供了多種選擇,一個是使用(Consul)來作DNS服務集羣,另外一個是(Consul)基於代理的API 網關。
每個微服務都關聯Eureka,在整個集羣中檢索API路由。使用這個策略,每個在集羣上運行的微服務只須要經過一個 共同的API網關進行負載均衡和暴露接口,每個服務也會自動發現並將路由請求轉發到本身的路由服務中。這個代理技術有助於開發用戶界面,做爲平臺完整的 API經過本身的主機映射爲代理服務。
下面的實例將會經過Maven來構建,使用Docker爲每個微服務構建容器鏡像.咱們能夠很優雅的使用Docker compose在咱們本身的主機上搭建所有的微服務集羣.
在這以前,請先移步至項目的GitHub 倉庫。
https://github.com/kbastani/spring-cloud-microservice-example
clone或者fork這個項目而且把源碼下載到您本身的電腦上。下載完畢後,你須要使用Maven和Docker 來編譯和構建本地的容器鏡像.
下載Docker
首先,若是你尚未Docker請先下載它。能夠跟隨這個 指南來獲取docker,安裝並運行在你的開發機上。
固然你也須要安裝 Docker Compose,這個 指南將會幫到你。
環境要求:
可以運行實例程序,須要在你的開發機上安裝下面的軟件:
經過命令行方式,構建當前項目,在項目的根目錄運行下面的命令.
$ mvn clean install
項目將會根據pom.xml中的每個項目聲明中下載相應的依賴jar包.每個服務將會被構建,同時Maven的Docker插件將會自動從本地 Docker registry中構建每個容器鏡像.Docker將會在構建成功後,根據命令行運行mvn clean install來清除相應的資源。
在項目成功構建後,你將會看到以下的輸出:
[INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary: [INFO] [INFO] spring-cloud-microservice-example-parent .......... SUCCESS [ 0.268 s] [INFO] users-microservice ................................ SUCCESS [ 11.929 s] [INFO] discovery-microservice ............................ SUCCESS [ 5.640 s] [INFO] api-gateway-microservice .......................... SUCCESS [ 5.156 s] [INFO] recommendation-microservice ....................... SUCCESS [ 7.732 s] [INFO] config-microservice ............................... SUCCESS [ 4.711 s] [INFO] hystrix-dashboard ................................. SUCCESS [ 4.251 s] [INFO] consul-microservice ............................... SUCCESS [ 6.763 s] [INFO] movie-microservice ................................ SUCCESS [ 8.359 s] [INFO] movies-ui ......................................... SUCCESS [ 15.833 s] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------
經過Docker compose 啓動集羣
如今每個鏡像都成功構建完畢,咱們使用Docker compose來加速啓動咱們的集羣.我已經將 Docker compose的yaml文件包含進了項目中,你們能夠從github上獲取。
如今,咱們經過下面的命令行啓動微服務集羣;
$ docker-compose up
若是一切配置都是正確的,每個容器鏡像將會經過在Docker上的虛擬容器和自動發現的網絡服務來運行。當他們開始順序啓動時,你將會看到一系列的日誌輸出。這可能須要一段時間來完成,取決於運行你實例程序的機器性能。
一旦容器啓動成功,你將會經過Eureka主機看到經過discovery service註冊上來的應用服務。
經過命令行終端複製粘貼下面的命令到Docker中定義的$DOCKER_HOST環境變量中.
$ open $(echo \"$(echo $DOCKER_HOST)\"| \sed 's/tcp:\/\//http:\/\//g'| \sed 's/[0-9]\{4,\}/8761/g'| \sed 's/\"//g')
若是Eureka正確的啓動,瀏覽器將會啓動並打開Eureka 服務的儀表盤,以下圖所示:
咱們將會看到每個正在運行的服務實例和狀態.經過下面的命令,獲取數據驅動服務,例如movie服務。
$ open $(echo \"$(echo $DOCKER_HOST)/movie\"| \sed 's/tcp:\/\//http:\/\//g'| \sed 's/[0-9]\{4,\}/10000/g'| \sed 's/\"//g')
這個命令將會訪問根據導航網關終端提供的代理方式訪問movie服務的REST API終端。這些REST APIs使用 HATEOAS 來配置,它是一個經過內嵌連接的方式支持自動發現服務的接口。
{ "_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構建微服務架構的系列博文的第一部分。在已經介紹完的博客中,咱們接觸到了以下的概念:
在這以後的博文中,咱們將會演示如何使用後臺服務來構建前端應用程序.同時也會介紹一個混合性持久化的實例,使用MySQL和Neo4j.