服務發現 - consul 的介紹、部署和使用(轉)

微服務的框架體系中,服務發現是不能不提的一個模塊。我相信瞭解或者熟悉微服務的童鞋應該都知道它的重要性。這裏我只是簡單的提一下,畢竟這不是咱們的重點。咱們看下面的一幅圖片:



圖中,客戶端的一個接口,須要調用服務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

相關文章
相關標籤/搜索