1. 程式人生 > 程式設計 >C#使用Consul叢集進行服務註冊與發現

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。