微服務的框架體系中,服務發現是不能不提的一個模塊。我相信瞭解或者熟悉微服務的童鞋應該都知道它的重要性。這裏我只是簡單的提一下,畢竟這不是咱們的重點。咱們看下面的一幅圖片:
圖中,客戶端的一個接口,須要調用服務A-N。客戶端必需要知道全部服務的網絡位置的,以往的作法是配置是配置文件中,或者有些配置在數據庫中。這裏就帶出幾個問題:
須要配置N個服務的網絡位置,加大配置的複雜性
服務的網絡位置變化,都須要改變每一個調用者的配置
集羣的狀況下,難以作負載(反向代理的方式除外)
總結起來一句話:服務多了,配置很麻煩,問題多多
既然有這些問題,那麼服務發現就是解決這些問題的。話說,怎麼解決呢?咱們再看一張圖
與以前一張不一樣的是,加了個服務發現模塊。圖比較簡單,這邊文字描述下。服務A-N把當前本身的網絡位置註冊到服務發現模塊(這裏註冊的意思就是告訴),服務發現就以K-V的方式記錄下,K通常是服務名,V就是IP:PORT。服務發現模塊定時的輪詢查看這些服務能不能訪問的了(這就是健康檢查)。客戶端在調用服務A-N的時候,就跑去服務發現模塊問下它們的網絡位置,而後再調用它們的服務。這樣的方式是否是就能夠解決上面的問題了呢?客戶端徹底不須要記錄這些服務網絡位置,客戶端和服務端徹底解耦!
這個過程大致是這樣,固然服務發現模塊沒這麼簡單。裏面包含的東西還不少。這樣表述只是方便理解。
圖中的服務發現模塊基本上就是微服務架構中服務發現的做用了。
consul 簡介
作服務發現的框架經常使用的有
zookeeper
eureka
etcd
consul
這裏就不比較哪一個好哪一個差了,須要的童鞋本身谷歌百度。
那麼consul是啥?consul就是提供服務發現的工具。而後下面是簡單的介紹:
consul是分佈式的、高可用、橫向擴展的。consul提供的一些關鍵特性:
service discovery:consul經過DNS或者HTTP接口使服務註冊和服務發現變的很容易,一些外部服務,例如saas提供的也能夠同樣註冊。
health checking:健康檢測使consul能夠快速的告警在集羣中的操做。和服務發現的集成,能夠防止服務轉發到故障的服務上面。
key/value storage:一個用來存儲動態配置的系統。提供簡單的HTTP接口,能夠在任何地方操做。
multi-datacenter:無需複雜的配置,便可支持任意數量的區域。
咱們這裏會介紹服務發現,健康檢查,還有一些基本KV存儲。多數據中心有機會另外一篇文章再說。
總結:只要知道它是解決我上一部分提出的問題就行,其它的東西慢慢理解
consul的幾個概念
上圖是我從consul官方文檔摳出來的。
咱們只看數據中心1,能夠看出consul的集羣是由N個SERVER,加上M個CLIENT組成的。而不論是SERVER仍是CLIENT,都是consul的一個節點,全部的服務均可以註冊到這些節點上,正是經過這些節點實現服務註冊信息的共享。除了這兩個,還有一些小細節,一一簡單介紹。
CLIENT
CLIENT表示consul的client模式,就是客戶端模式。是consul節點的一種模式,這種模式下,全部註冊到當前節點的服務會被轉發到SERVER,自己是不持久化這些信息。
SERVER
SERVER表示consul的server模式,代表這個consul是個server,這種模式下,功能和CLIENT都同樣,惟一不一樣的是,它會把全部的信息持久化的本地,這樣遇到故障,信息是能夠被保留的。
SERVER-LEADER
中間那個SERVER下面有LEADER的字眼,代表這個SERVER是它們的老大,它和其它SERVER不同的一點是,它須要負責同步註冊的信息給其它的SERVER,同時也要負責各個節點的健康監測。
其它信息
其它信息包括它們之間的通訊方式,還有一些協議信息,算法。它們是用於保證節點之間的數據同步,實時性要求等等一系列集羣問題的解決。這些有興趣的本身看看官方文檔。
consul 基本使用
本身就一臺機子,因此這裏就演示下docker下部署使用consul。容器與宿主機的端口映射忽略,正常生產環境每一個宿主機一個consul,端口須要映射到宿主機html
Consul 命令簡單介紹node
agent : 表示啓動 Agent 進程。
-server:表示啓動 Consul Server 模式。
-client:表示啓動 Consul Cilent 模式。
-bootstrap:表示這個節點是 Server-Leader ,每一個數據中心只能運行一臺服務器。技術角度上講 Leader 是經過 Raft 算法選舉的,可是集羣第一次啓動時須要一個引導 Leader,在引導羣集後,建議不要使用此標誌。
-ui:表示啓動 Web UI 管理器,默認開放端口 8500,因此上面使用 Docker 命令把 8500 端口對外開放。
-node:節點的名稱,集羣中必須是惟一的。
-client:表示 Consul 將綁定客戶端接口的地址,0.0.0.0 表示全部地址均可以訪問。
-join:表示加入到某一個集羣中去。 如:-json=192.168.1.23
部署git
拉取鏡像github
docker search consul
我們用官方的鏡像玩玩
算法
docker pull consul
不指定tag就拉取last,當前版本是0.8.0spring
配置docker 網絡
由於docker 默認的 docker0 虛擬網卡是不支持直接設置靜態ip的。因此咱們先建立一個本身的虛擬網絡。
docker
sudo docker network create --subnet=172.17.0.0/24 staticnet
執行完能夠經過 下面了命令查看
數據庫
sudo docker network
PS:
json
私有網絡ip選取小知識: 這三個地址段分別位於A、B、C三類地址內: A類地址:10.0.0.0--10.255.255.255 B類地址:172.16.0.0--172.31.255.255 C類地址:192.168.0.0--192.168.255.255
啓動consul
啓動節點1(server模式)
bootstrap
docker run -d -p 8500:8500 -v /data/consul:/consul/data -e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}' --name=consul_server_node1 consul agent -server -bind=172.17.0.2 -bootstrap-expect=3 -ui -node=node1 -client='0.0.0.0'
-node:節點的名稱
-bind:綁定的一個地址,用於節點之間通訊的地址,能夠是內外網,必須是能夠訪問到的地址
-server:這個就是表示這個節點是個SERVER
-bootstrap-expect:這個就是表示指望提供的SERVER節點數目,數目一達到,它就會被激活,而後就是LEADER了
啓動節點2-3(server模式)
docker run -d -e 'CONSUL_LOCAL_CONFIG={"skip_leave_on_interrupt": true}' --name=consul_server_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=consul_server_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。
啓動節點4(client模式)
docker run -d -e 'CONSUL_LOCAL_CONFIG={"leave_on_terminate": true}' --name=consul_client_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。
節點異常consul的處理
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」
存儲個K/V
設置一個值到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使用
若是是使用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
引用和附件
Consul 原理和使用簡介 : https://blog.coding.net/blog/intro-consul?type=hot
Consul 鏡像倉庫地址 :https://hub.docker.com/_/consul
Consul 鏡像使用文檔:https://github.com/docker-library/docs/tree/master/consul
Consul 官方文檔 :https://www.consul.io/docs/agent/basics.html
使用Consul和Registration對Docker容器進行服務發現
https://livewyer.io/blog/2015/02/05/service-discovery-docker-containers-using-consul-and-registrator
基於Consul+Registrator+Nginx實現容器服務自動發現的集羣框架
http://www.mamicode.com/info-detail-2222200.html
.NET Core微服務之基於Consul實現服務治理
https://www.cnblogs.com/edisonchou/p/9124985.html