服务发现 - 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,端口需要映射到宿主機
部署
拉取鏡像
? ?
咱們用官方的鏡像玩玩
? ?
docker pull consul
不指定tag就拉取last,當前版本是1.4.2
啟動consul
啟動節點1(server模式)
-node:節點的名稱?
-bind:綁定的一個地址,用于節點之間通信的地址,可以是內外網,必須是可以訪問到的地址?
-server:這個就是表示這個節點是個SERVER?
-bootstrap-expect:這個就是表示期望提供的SERVER節點數目,數目一達到,它就會被激活,然后就是LEADER了啟動節點2-3(server模式)
-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=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
查看下集群的狀態
?
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://ip:8500/v1/status/leader
1
返回的內容:
? "ip:8300"
1
ip就是 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://ip8500/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
1
返回的響應:
[
? ? {
? ? ? ? "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
1
獲取特定的值
docker exec -t node1 consul kv get -detailed user/config/connections
1
值的內容為5,還有key等相關的值
總結
服務發現以及配置共享的簡單樣例展示了下,詳細的使用還是需要看官方文檔,這里只是列舉了一些樣例,用于理解和簡單的使用consul。
?
總結
以上是生活随笔為你收集整理的服务发现 - consul 的介绍、部署和使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CentOS7 DNS的添加
- 下一篇: yum使用指南