C#使用Consul集群進行服務註冊與發現

来源:https://www.cnblogs.com/kiba/archive/2019/12/06/11941731.html
-Advertisement-
Play Games

前言 我個人覺得,中間件的部署與使用是非常難記憶的;也就是說,如果兩次使用中間件的時間間隔比較長,那基本上等於要重新學習使用。 所以,我覺得學習中間件的文章,越詳細越好;因為,這對作者而言也是一份珍貴的備忘資料。 Consul簡介 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

----------------------------------------------------------------------------------------------------

註:此文章為原創,任何形式的轉載都請聯繫作者獲得授權並註明出處!
若您覺得這篇文章還不錯,請點擊下方的推薦】,非常感謝!

https://www.cnblogs.com/kiba/p/11703073.html

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 阿裡雲的CentOS 7.7 64位,所需要的環境:MySql 5.7,.Net Core 2.2 ,Nginx 我這裡用的 Xshell 工具,首先用root進入系統 版本信息 打開終端輸入命令: lsb_release -a 安裝 .Net Core 2.2 SDK 官網參考文檔:https:/ ...
  • 有C#基礎的,當問到迴圈有哪些,會毫不猶豫的說出的for、do while、foreach及while這幾種,但是到具體實際開發中,我們遇到一些問題,比如:到底選擇哪種?為什麼選擇這種?哪種好像都可以?,其實在大多數情況下基本上可以通用,但是遇到比如Dictionary <[key] , [valu... ...
  • 前言 按需載入對象延遲載入實際是推遲進行創建對象,直到對其調用後才進行創建初始化,延遲(懶載入)的好處是提高系統性能,避免不必要的計算以及不必要的資源浪費。 常規有這些情況: 對象創建成本高且程式可能不會使用它。 例如,假定記憶體中有具有 Orders 屬性的 Customer 對象,該對象包含大量 ...
  • 本筆記摘抄自:https://www.cnblogs.com/zhili/archive/2012/07/21/ThreadsSynchronous.html,記錄一下學習過程以備後續查用。 一、線程同步概述 創建多線程來實現讓我們能夠更好地響應應用程式,然而當我們創建了多個線程時,就存在多個線程同 ...
  • .NET Core Blazor 1 Blazor項目文件分析 本節內容為Blazor的基本文件 簡介 Blazor是一個使用.NET技術用於代替JavaScript/typescript的前端WEB框架。在前端開發中使用.NET語言進行書寫邏輯有利於我們的性能、可靠性和安全性。並且對於使用.NET ...
  • 遇到的問題/需求 1. 這裡會把一些敏感的參數記錄下來,我們需要屏蔽掉,如圖 2. 我們希望日誌裡面有當前登錄用戶的信息,如圖: 處理方法 tip:這裡用的是.net非.net core 第一個問題(屏蔽敏感參數): 第二個問題(添加擴展信息) 直接看代碼/註釋吧 當然需要在 的 方法中調用 其他 ...
  • 原文:https://blogs.msdn.microsoft.com/mazhou/2017/05/30/c-7-series-part-2-async-main/ 你大概知道,C#語言可以構建兩種程式。一種是帶有入口點(entrypoint)的程式,這樣操作系統就可以載入程式並從入口點執行;另一 ...
  • Dev 複合表頭的使用 作為一名開發小白,開發時遇到使用複合表頭,此前沒有使用過,浪費很多時間弄出,此為本人經驗,僅供參考。 1.首先針對於VS裡面增加了Dev控制項來說,創建WinForm頁面後拖動GridControl 到表單中 2.頁面中有 Click here to change view, ...
一周排行
    -Advertisement-
    Play Games
  • C#TMS系統代碼-基礎頁面BaseCity學習 本人純新手,剛進公司跟領導報道,我說我是java全棧,他問我會不會C#,我說大學學過,他說這個TMS系統就給你來管了。外包已經把代碼給我了,這幾天先把增刪改查的代碼背一下,說不定後面就要趕鴨子上架了 Service頁面 //using => impo ...
  • 委托與事件 委托 委托的定義 委托是C#中的一種類型,用於存儲對方法的引用。它允許將方法作為參數傳遞給其他方法,實現回調、事件處理和動態調用等功能。通俗來講,就是委托包含方法的記憶體地址,方法匹配與委托相同的簽名,因此通過使用正確的參數類型來調用方法。 委托的特性 引用方法:委托允許存儲對方法的引用, ...
  • 前言 這幾天閑來沒事看看ABP vNext的文檔和源碼,關於關於依賴註入(屬性註入)這塊兒產生了興趣。 我們都知道。Volo.ABP 依賴註入容器使用了第三方組件Autofac實現的。有三種註入方式,構造函數註入和方法註入和屬性註入。 ABP的屬性註入原則參考如下: 這時候我就開始疑惑了,因為我知道 ...
  • C#TMS系統代碼-業務頁面ShippingNotice學習 學一個業務頁面,ok,領導開完會就被裁掉了,很突然啊,他收拾東西的時候我還以為他要旅游提前請假了,還在尋思為什麼回家連自己買的幾箱飲料都要叫跑腿帶走,怕被偷嗎?還好我在他開會之前拿了兩瓶芬達 感覺感覺前面的BaseCity差不太多,這邊的 ...
  • 概述:在C#中,通過`Expression`類、`AndAlso`和`OrElse`方法可組合兩個`Expression<Func<T, bool>>`,實現多條件動態查詢。通過創建表達式樹,可輕鬆構建複雜的查詢條件。 在C#中,可以使用AndAlso和OrElse方法組合兩個Expression< ...
  • 閑來無聊在我的Biwen.QuickApi中實現一下極簡的事件匯流排,其實代碼還是蠻簡單的,對於初學者可能有些幫助 就貼出來,有什麼不足的地方也歡迎板磚交流~ 首先定義一個事件約定的空介面 public interface IEvent{} 然後定義事件訂閱者介面 public interface I ...
  • 1. 案例 成某三甲醫預約系統, 該項目在2024年初進行上線測試,在正常運行了兩天後,業務系統報錯:The connection pool has been exhausted, either raise MaxPoolSize (currently 800) or Timeout (curren ...
  • 背景 我們有些工具在 Web 版中已經有了很好的實踐,而在 WPF 中重新開發也是一種費時費力的操作,那麼直接集成則是最省事省力的方法了。 思路解釋 為什麼要使用 WPF?莫問為什麼,老 C# 開發的堅持,另外因為 Windows 上已經裝了 Webview2/edge 整體打包比 electron ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...