http://blog.csdn.net/buxiaoxia/article/details/69788114html
相關源碼: spring cloud demonode
微服務的框架體系中,服務發現是不能不提的一個模塊。我相信瞭解或者熟悉微服務的童鞋應該都知道它的重要性。這裏我只是簡單的提一下,畢竟這不是咱們的重點。咱們看下面的一幅圖片:git
圖中,客戶端的一個接口,須要調用服務A-N。客戶端必需要知道全部服務的網絡位置的,以往的作法是配置是配置文件中,或者有些配置在數據庫中。這裏就帶出幾個問題:github
總結起來一句話:服務多了,配置很麻煩,問題多多算法
既然有這些問題,那麼服務發現就是解決這些問題的。話說,怎麼解決呢?咱們再看一張圖spring
與以前一張不一樣的是,加了個服務發現模塊。圖比較簡單,這邊文字描述下。服務A-N把當前本身的網絡位置註冊到服務發現模塊(這裏註冊的意思就是告訴),服務發現就以K-V的方式記錄下,K通常是服務名,V就是IP:PORT。服務發現模塊定時的輪詢查看這些服務能不能訪問的了(這就是健康檢查)。客戶端在調用服務A-N的時候,就跑去服務發現模塊問下它們的網絡位置,而後再調用它們的服務。這樣的方式是否是就能夠解決上面的問題了呢?客戶端徹底不須要記錄這些服務網絡位置,客戶端和服務端徹底解耦!docker
這個過程大致是這樣,固然服務發現模塊沒這麼簡單。裏面包含的東西還不少。這樣表述只是方便理解。數據庫
圖中的服務發現模塊基本上就是微服務架構中服務發現的做用了。json
作服務發現的框架經常使用的有bootstrap
這裏就不比較哪一個好哪一個差了,須要的童鞋本身谷歌百度。
那麼consul是啥?consul就是提供服務發現的工具。而後下面是簡單的介紹:
consul是分佈式的、高可用、橫向擴展的。consul提供的一些關鍵特性:
咱們這裏會介紹服務發現,健康檢查,還有一些基本KV存儲。多數據中心有機會另外一篇文章再說。
總結:只要知道它是解決我上一部分提出的問題就行,其它的東西慢慢理解
上圖是我從consul官方文檔摳出來的。
咱們只看數據中心1,能夠看出consul的集羣是由N個SERVER,加上M個CLIENT組成的。而不論是SERVER仍是CLIENT,都是consul的一個節點,全部的服務均可以註冊到這些節點上,正是經過這些節點實現服務註冊信息的共享。除了這兩個,還有一些小細節,一一簡單介紹。
CLIENT表示consul的client模式,就是客戶端模式。是consul節點的一種模式,這種模式下,全部註冊到當前節點的服務會被轉發到SERVER,自己是不持久化這些信息。
SERVER表示consul的server模式,代表這個consul是個server,這種模式下,功能和CLIENT都同樣,惟一不一樣的是,它會把全部的信息持久化的本地,這樣遇到故障,信息是能夠被保留的。
中間那個SERVER下面有LEADER的字眼,代表這個SERVER是它們的老大,它和其它SERVER不同的一點是,它須要負責同步註冊的信息給其它的SERVER,同時也要負責各個節點的健康監測。
其它信息包括它們之間的通訊方式,還有一些協議信息,算法。它們是用於保證節點之間的數據同步,實時性要求等等一系列集羣問題的解決。這些有興趣的本身看看官方文檔。
本身就一臺機子,因此這裏就演示下docker下部署使用consul。容器與宿主機的端口映射忽略,正常生產環境每一個宿主機一個consul,端口須要映射到宿主機
docker search consul
我們用官方的鏡像玩玩
docker pull consul
不指定tag就拉取last,當前版本是0.8.0
docker run -d -e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}' --name=node1 consul agent -server -bind=172.17.0.2 -bootstrap-expect=3 -node=node1
-node:節點的名稱
-bind:綁定的一個地址,用於節點之間通訊的地址,能夠是內外網,必須是能夠訪問到的地址
-server:這個就是表示這個節點是個SERVER
-bootstrap-expect:這個就是表示指望提供的SERVER節點數目,數目一達到,它就會被激活,而後就是LEADER了
docker run -d -e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}' --name=node2 consul agent -server -bind=172.17.0.3 -join=172.17.0.2 -node-id=$(uuidgen | awk '{print tolower($0)}') -node=node2 docker run -d -e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}' --name=node3 consul agent -server -bind=172.17.0.4 -join=172.17.0.2 -node-id=$(uuidgen | awk '{print tolower($0)}') -node=node3 -client=172.17.0.4
-join:這個表示啓動的時候,要加入到哪一個集羣內,這裏就是說要加入到節點1的集羣
-node-id:這個貌似版本8才加入的,這裏用這個來指定惟一的節點ID,能夠查看這個issue
-client:這個表示註冊或者查詢等一系列客戶端對它操做的IP,若是不指定這個IP,默認是127.0.0.1。
docker run -d -e 'CONSUL_LOCAL_CONFIG={"leave_on_terminate": true}' --name=node4 consul agent -bind=172.17.0.5 -retry-join=172.17.0.2 -node-id=$(uuidgen | awk '{print tolower($0)}') -node=node4
除了沒有-server,其它都是同樣的,沒有這個就說明這個節點是CLIENT
docker exec -t node1 consul members
4個節點都列出來了。Status表示它們的狀態,都是alive。Type表示它們的類型,三個SERVER一個CLIENT,和咱們以前啓動的同樣。DC表示數據中心,都是dc1。
LEADER 掛了
leader掛了,consul會從新選取出新的leader,只要超過一半的SERVER還活着,集羣是能夠正常工做的。node1是leader,因此把這個容器停了。
docker stop node1
看看其餘節點的日誌(node2):
日誌打印,心跳檢查node1的ip超時,接着開始選舉。node2被選舉爲新的leader。咱們查看下如今的leader:
curl http://172.17.0.4:8500/v1/status/leader
返回的內容:
"172.17.0.3:8300"
172.17.0.3 就是 node2節點的IP
部署完了,那麼能夠看看怎麼用這個東東了。
使用HTTP API 註冊個服務,使用[接口API](https://www.consul.io/api/agent/service.html API)調用
調用 http://consul:8500/v1/agent/service/register PUT 註冊一個服務。request body:
{
"ID": "userServiceId", //服務id "Name": "userService", //服務名 "Tags": [ //服務的tag,自定義,能夠根據這個tag來區分同一個服務名的服務 "primary", "v1" ], "Address": "127.0.0.1",//服務註冊到consul的IP,服務發現,發現的就是這個IP "Port": 8000, //服務註冊consul的PORT,發現的就是這個PORT "EnableTagOverride": false, "Check": { //健康檢查部分 "DeregisterCriticalServiceAfter": "90m", "HTTP": "http://www.baidu.com", //指定健康檢查的URL,調用後只要返回20X,consul都認爲是健康的 "Interval": "10s" //健康檢查間隔時間,每隔10s,調用一次上面的URL } }
使用curl調用
curl http://172.17.0.4:8500/v1/agent/service/register -X PUT -i -H "Content-Type:application/json" -d '{ "ID": "userServiceId", "Name": "userService", "Tags": [ "primary", "v1" ], "Address": "127.0.0.1", "Port": 8000, "EnableTagOverride": false, "Check": { "DeregisterCriticalServiceAfter": "90m", "HTTP": "http://www.baidu.com", "Interval": "10s" } }'
OK,註冊了一個服務
剛剛註冊了名爲userService的服務,咱們如今發現(查詢)下這個服務
curl http://172.17.0.4:8500/v1/catalog/service/userService
返回的響應:
[
{
"Address": "172.17.0.4", "CreateIndex": 880, "ID": "e6e9a8cb-c47e-4be9-b13e-a24a1582e825", "ModifyIndex": 880, "Node": "node3", "NodeMeta": {}, "ServiceAddress": "127.0.0.1", "ServiceEnableTagOverride": false, "ServiceID": "userServiceId", "ServiceName": "userService", "ServicePort": 8000, "ServiceTags": [ "primary", "v1" ], "TaggedAddresses": { "lan": "172.17.0.4", "wan": "172.17.0.4" } } ]
內容有了吧,這個就是咱們剛剛註冊的服務的信息,就能夠獲取到
服務的名稱是「userService」
服務地址是「127.0.0.1」
服務的端口是「8000」
設置一個值到user/config/connections 內容爲5
docker exec -t node1 consul kv put user/config/connections 5
獲取特定的值
docker exec -t node1 consul kv get -detailed user/config/connections
值的內容爲5,還有key等相關的值
服務發現以及配置共享的簡單樣例展現了下,詳細的使用仍是須要看官方文檔,這裏只是列舉了一些樣例,用於理解和簡單的使用consul。
若是是使用spring cloud來使用consul,能夠查看個人相關樣例:http://git.oschina.net/buxiaoxia/spring-demo
spring cloud 結合consul的使用,下一篇文章再進行描述吧
CONSUL:https://www.consul.io/
CONSUL HTTP API:https://www.consul.io/api/index.html
CONSUL CLI:https://www.consul.io/docs/commands/info.html
CONSUL Health Checks:https://www.consul.io/docs/agent/checks.html