C#使用Consul叢集進行服務註冊與發現
前言
我個人覺得,中介軟體的部署與使用是非常難記憶的;也就是說,如果兩次使用中介軟體的時間間隔比較長,那基本上等於要重新學習使用。
所以,我覺得學習中介軟體的文章,越詳細越好;因為,這對作者而言也是一份珍貴的備忘資料。
Consul簡介
Consul一個什麼,我想大家通過搜尋引擎一定可以搜尋到;所以,我就不在重複他的官方描述了。
這裡,我為大家提供一個更加好理解的描述。
Consul是什麼?
Consul本質上是一個Socket通訊中介軟體。
它主要實現了兩個功能,服務註冊與發現與自身的負載均衡的叢集。
我們可以把他理解為一個沒有介面的應用程式,因為沒有介面,所以想啟動Consul就只能使用命令行了;也因為沒有介面,一旦使用命令列啟動了Consul,那麼,執行該命令列的cmd.exe程式,就成了Consul的宿主了;一旦關閉Cmd視窗,Consul就停止運行了。
服務註冊與發現的本質是什麼?
其實服務註冊與發現的原理很簡單。
當我們在本機執行Consul時,他會自動監聽8500埠;然後我們通過一個開源類庫(這個開源類庫可以在nuget上檢索到,文章下面會介紹),呼叫其下不同的方法來向這個Consul程序傳送TCP訊息,來註冊服務或者發現服務。
Consul程序在接收到註冊訊息時,就把註冊的服務資訊儲存到本地磁碟或記憶體(因為我沒有具體去調查Consul儲存資料是否使用了資料庫,但我們都知道資料庫的資料也是儲存在本地磁碟的,所以,它肯定是把資料存進磁碟或者記憶體中了)。
資料中心
Consul儲存資料的地方,官方為其命名為資料中心,也就是上面說的儲存我們註冊的服務資訊的本地磁碟或者記憶體。
Consul提供負載均衡的叢集
Consul的叢集也很好理解,在我們成功啟動Consul以後,它除了監聽8500埠以外,它還監聽了一個8031埠。
這個8031埠就是用於Consul叢集相互通訊的。
我們都知道叢集是要兩臺以上的電腦的,所以,我們就必須找到兩臺或以上的電腦安裝Consul中介軟體。
然後,使用Consul的命令列,將兩臺電腦連線到一起,這樣叢集就形成了。
在叢集內每臺電腦上安裝的Consul中介軟體,我們統稱為伺服器代理(Agent);當叢集啟動後,會在多個代理伺服器之間選舉出一個Leader。
選舉Leader自然就是伺服器代理之間的通訊了,也就是通過上面提到的8031埠通訊的。
選舉了Leader,伺服器代理就可以將自身的負載資訊傳送給Leader了,這樣客戶端呼叫Consul檢索服務資料時,就可以去效能最優的那臺機器上獲取資訊了。(注:這個就是舉例說明,並非Consul的負載均衡的真實處理模式)
Consul代理伺服器安裝
首先,去官網下載Consul,官網下載地址https://www.consul.io/downloads.html
拉到網站的最下方,選擇Window64-bit的Consul下載,如下圖:
下載完成後,我們得到一個壓縮包consul_1.6.2_windows_amd64.zip;解壓縮後,得到consul.exe檔案,如下圖:
因為我們要使用命令列來執行consul,所以,我們將consul.exe所在的目錄新增進環境變數,這樣,當我們在CMD視窗中執行consul的相關命令時,系統就會自動將這個些命令傳送給consul.exe檔案執行了。
配置環境變數如下圖所示:
配置完環境變數,我們開啟一個cmd的命令列視窗,然後輸入consul來確認我們的環境變數是否配置成功,如下圖:
看到圖中的資訊,就代表我們的consul的環境變數配置成功了,已經可以運行了。
接下來,我們在這個cmd窗體中輸入consul的命令來啟動consul伺服器代理,命令如下:
命令解釋如下:
consul agent -server -ui -bootstrap-expect=1 -data-dir=/tmp/consul -node=consul-1 -client=0.0.0.0 -bind=192.168.1.111 -datacenter=dc1
其實consul命令大家是可以在網路上搜到它們的定義的,不過我覺得解釋的還是太官方,所以,我在這裡提供了一份我認為更好的解釋。
consul agent:命令頭,必須要有。
-server:表面我們現在要啟動伺服器代理(agent)是服務模式的。Consul Agent的執行模式有兩種,Server模式和Client模式。其區別簡單來說就是Server模式的Agent可以被選舉為Leader,而Client模式的不可以,當然還有其他區別,有興趣大家可以自行了解。
-ui:consul執行後,會提供一個http://127.0.0.1:8500/ui/的網站,裡面儲存了Consul Agent各個節點以及註冊的服務等相關資訊,即資料中心的網頁形式體現。這個引數代表是否建立這個網站,這個引數與這個資料中心網站有關。
bind:本機的ip地址,叢集內其他代理伺服器可以通過這個ip來訪問這臺電腦的consul代理伺服器。
bootstrap-expect:是叢集啟動條件,指當伺服器端模式(Server模式)的代理達到這個數目後,才開始執行。
data-dir:是存放資料中心資料的,該目錄必須是穩定的,系統重啟後也繼續存在的。
datacenter:當前agent的中心資料的名稱,預設是dc1。
node:節點在叢集中的名稱,在一個叢集中必須是唯一的,預設是該節點的主機名(代表一個機器)。
client:本地ip地址,這裡使用 0.0.0.0 ,就表示這個伺服器所有IP都可以,即當這臺電腦有倆ip,192.168.1.111和192.168.1.112,那麼通過這倆IP都可以訪問到這臺機器的consul代理伺服器。
執行該命令,如下圖所示:
可以看到,我們的Consul代理服務已經成功運行了。
現在,我們在去另一臺電腦,開啟cmd視窗,執行如下consul命令:
consul agent -server -ui -bootstrap-expect=1 -data-dir=d:\consul -node=consul-2 -client=0.0.0.0 -bind=192.168.80.112 -datacenter=dc1 -join 192.168.80.111
可以看到,我們在命令列最後面追加了一個join 192.168.80.111;通過這個命令,我們把這臺電腦的代理伺服器成功的加入到了上文中的consul叢集。
服務註冊與發現
Consul的服務註冊
首先,我們建立一個WebAPI,這裡為使用了Core框架建立了一個Web API,為了方便測試,我就直接拿本地的VisualStudio啟動測試了。
建立WebAPI後,我們在Nuget中查詢Consul的Net版本類庫。
在Nuget中搜索Consul,然後選中下圖中的選項進行安裝。
然後,我們在Startup檔案中,增加一個函式,如下:
public static void RegisterConsul() { var consulClient = new ConsulClient(p => { p.Address = new Uri($"http://127.0.0.1:8500"); });//請求註冊的 Consul 地址 //這裡的這個ip 就是本機的ip,這個埠8500 這個是預設註冊服務埠 var httpCheck = new AgentServiceCheck() { DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服務啟動多久後註冊 Interval = TimeSpan.FromSeconds(10),//間隔固定的時間訪問一次,https://localhost:44308/api/Health HTTP = $"https://localhost:44308/api/Health",//健康檢查地址 44308是visualstudio啟動的埠 Timeout = TimeSpan.FromSeconds(5) }; var registration = new AgentServiceRegistration() { Checks = new[] { httpCheck },ID = Guid.NewGuid().ToString(),Name = "test1",Address = "https://localhost/",Port = 44308,}; consulClient.Agent.ServiceRegister(registration).Wait();//註冊服務 //consulClient.Agent.ServiceDeregister(registration.ID).Wait();//registration.ID是guid //當服務停止時需要取消服務註冊,不然,下次啟動服務時,會再註冊一個服務。 //但是,如果該服務長期不啟動,那consul會自動刪除這個服務,大約2,3分鐘就會刪了 }
然後在Configure中呼叫這個方法,這樣,當我們除錯或執行這個專案時,就會自動將這個Webapi註冊到Consul裡了。
public void Configure(IApplicationBuilder app,IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); RegisterConsul();//註冊本服務到consul叢集 }
服務註冊完後,可以訪問本地資料中心的網站【http://127.0.0.1:8500/ui/dc1/services】來檢視註冊服務的狀態。
Consul服務發現
服務註冊完成後,我們再建立一個控制檯專案來進行服務發現。
建立完成專案後,也需要引用consul類庫,同服務端一樣在Nuget中搜索。
編寫程式碼如下:
static void Main(string[] args) { var consulClient = new ConsulClient(x => x.Address = new Uri($"http://192.168.1.178:8500"));//請求註冊的 Consul 地址 var ret = consulClient.Agent.Services(); var allServer = ret.GetAwaiter().GetResult(); //這個是個dictionary的返回值,他的key是string型別,就是8500/ui上services的instance的id var allServerDic = allServer.Response; var test1 = allServerDic.First(); string name = test1.Value.Service;//服務名,就是註冊的那個test1 string serverAddress = test1.Value.Address; int serverPort = test1.Value.Port; Console.WriteLine($"serverAddress:{serverAddress}==serverPort{serverPort}"); //我們可以在客戶端啟動的時候,呼叫一下consul來查詢服務 //比如,我們可以在服務集合裡查詢 服務名叫test1的服務 然後在呼叫它 //這樣,當伺服器改變了test1的ip和埠,我們依然可以在叢集裡找他test1新的ip和埠了 Console.ReadKey(); }
執行結果如下:
可以看到,我們已經成功呼叫了Consul,也成功的獲取到了服務資訊。
其實Consul除了服務註冊與查詢,還可以進行Key-Value儲存,也就是說,這個是一個分散式Key-Value儲存叢集。
Key-Value儲存的用法在Github已經有例子了,網址:https://github.com/PlayFab/consuldotnet。
C#使用Consul進行服務註冊與發現就講完了。
程式碼已經傳到Github上了,歡迎大家下載。
Github地址:https://github.com/kiba518/KibaConsul
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。