C#使用Consul集群進(jìn)行服務(wù)注冊(cè)與發(fā)現(xiàn)
前言
我個(gè)人覺得,中間件的部署與使用是非常難記憶的;也就是說,如果兩次使用中間件的時(shí)間間隔比較長(zhǎng),那基本上等于要重新學(xué)習(xí)使用。
所以,我覺得學(xué)習(xí)中間件的文章,越詳細(xì)越好;因?yàn)?,這對(duì)作者而言也是一份珍貴的備忘資料。
Consul簡(jiǎn)介
Consul一個(gè)什么,我想大家通過搜索引擎一定可以搜索到;所以,我就不在重復(fù)他的官方描述了。
這里,我為大家提供一個(gè)更加好理解的描述。
Consul是什么?
Consul本質(zhì)上是一個(gè)Socket通信中間件。
它主要實(shí)現(xiàn)了兩個(gè)功能,服務(wù)注冊(cè)與發(fā)現(xiàn)與自身的負(fù)載均衡的集群。
我們可以把他理解為一個(gè)沒有界面的應(yīng)用程序,因?yàn)闆]有界面,所以想啟動(dòng)Consul就只能使用命令行了;也因?yàn)闆]有界面,一旦使用命令行啟動(dòng)了Consul,那么,執(zhí)行該命令行的cmd.exe程序,就成了Consul的宿主了;一旦關(guān)閉Cmd窗口,Consul就停止運(yùn)行了。
服務(wù)注冊(cè)與發(fā)現(xiàn)的本質(zhì)是什么?
其實(shí)服務(wù)注冊(cè)與發(fā)現(xiàn)的原理很簡(jiǎn)單。
當(dāng)我們?cè)诒緳C(jī)運(yùn)行Consul時(shí),他會(huì)自動(dòng)監(jiān)聽8500端口;然后我們通過一個(gè)開源類庫(這個(gè)開源類庫可以在nuget上檢索到,文章下面會(huì)介紹),調(diào)用其下不同的方法來向這個(gè)Consul進(jìn)程發(fā)送TCP消息,來注冊(cè)服務(wù)或者發(fā)現(xiàn)服務(wù)。
Consul進(jìn)程在接收到注冊(cè)消息時(shí),就把注冊(cè)的服務(wù)信息存儲(chǔ)到本地磁盤或內(nèi)存(因?yàn)槲覜]有具體去調(diào)查Consul存儲(chǔ)數(shù)據(jù)是否使用了數(shù)據(jù)庫,但我們都知道數(shù)據(jù)庫的數(shù)據(jù)也是保存在本地磁盤的,所以,它肯定是把數(shù)據(jù)存進(jìn)磁盤或者內(nèi)存中了)。
數(shù)據(jù)中心
Consul存儲(chǔ)數(shù)據(jù)的地方,官方為其命名為數(shù)據(jù)中心,也就是上面說的保存我們注冊(cè)的服務(wù)信息的本地磁盤或者內(nèi)存。
Consul提供負(fù)載均衡的集群
Consul的集群也很好理解,在我們成功啟動(dòng)Consul以后,它除了監(jiān)聽8500端口以外,它還監(jiān)聽了一個(gè)8031端口。
這個(gè)8031端口就是用于Consul集群相互通信的。
我們都知道集群是要兩臺(tái)以上的電腦的,所以,我們就必須找到兩臺(tái)或以上的電腦安裝Consul中間件。
然后,使用Consul的命令行,將兩臺(tái)電腦連接到一起,這樣集群就形成了。
在集群內(nèi)每臺(tái)電腦上安裝的Consul中間件,我們統(tǒng)稱為服務(wù)器代理(Agent);當(dāng)集群?jiǎn)?dòng)后,會(huì)在多個(gè)代理服務(wù)器之間選舉出一個(gè)Leader。
選舉Leader自然就是服務(wù)器代理之間的通信了,也就是通過上面提到的8031端口通信的。
選舉了Leader,服務(wù)器代理就可以將自身的負(fù)載信息發(fā)送給Leader了,這樣客戶端調(diào)用Consul檢索服務(wù)數(shù)據(jù)時(shí),就可以去性能最優(yōu)的那臺(tái)機(jī)器上獲取信息了。(注:這個(gè)就是舉例說明,并非Consul的負(fù)載均衡的真實(shí)處理模式)
Consul代理服務(wù)器安裝
首先,去官網(wǎng)下載Consul,官網(wǎng)下載地址https://www.consul.io/downloads.html
拉到網(wǎng)站的最下方,選擇Window64-bit的Consul下載,如下圖:
下載完成后,我們得到一個(gè)壓縮包c(diǎn)onsul_1.6.2_windows_amd64.zip;解壓縮后,得到consul.exe文件,如下圖:
因?yàn)槲覀円褂妹钚衼磉\(yùn)行consul,所以,我們將consul.exe所在的目錄添加進(jìn)環(huán)境變量,這樣,當(dāng)我們?cè)贑MD窗口中執(zhí)行consul的相關(guān)命令時(shí),系統(tǒng)就會(huì)自動(dòng)將這個(gè)些命令發(fā)送給consul.exe文件執(zhí)行了。
配置環(huán)境變量如下圖所示:
配置完環(huán)境變量,我們打開一個(gè)cmd的命令行窗口,然后輸入consul來確認(rèn)我們的環(huán)境變量是否配置成功,如下圖:
看到圖中的信息,就代表我們的consul的環(huán)境變量配置成功了,已經(jīng)可以運(yùn)行了。
接下來,我們?cè)谶@個(gè)cmd窗體中輸入consul的命令來啟動(dòng)consul服務(wù)器代理,命令如下:
命令解釋如下:
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
其實(shí)consul命令大家是可以在網(wǎng)絡(luò)上搜到它們的定義的,不過我覺得解釋的還是太官方,所以,我在這里提供了一份我認(rèn)為更好的解釋。
consul agent:命令頭,必須要有。
-server:表面我們現(xiàn)在要啟動(dòng)服務(wù)器代理(agent)是服務(wù)模式的。Consul Agent的運(yùn)行模式有兩種,Server模式和Client模式。其區(qū)別簡(jiǎn)單來說就是Server模式的Agent可以被選舉為L(zhǎng)eader,而Client模式的不可以,當(dāng)然還有其他區(qū)別,有興趣大家可以自行了解。
-ui:consul運(yùn)行后,會(huì)提供一個(gè)http://127.0.0.1:8500/ui/的網(wǎng)站,里面存儲(chǔ)了Consul Agent各個(gè)節(jié)點(diǎn)以及注冊(cè)的服務(wù)等相關(guān)信息,即數(shù)據(jù)中心的網(wǎng)頁形式體現(xiàn)。這個(gè)參數(shù)代表是否創(chuàng)建這個(gè)網(wǎng)站,這個(gè)參數(shù)與這個(gè)數(shù)據(jù)中心網(wǎng)站有關(guān)。
bind:本機(jī)的ip地址,集群內(nèi)其他代理服務(wù)器可以通過這個(gè)ip來訪問這臺(tái)電腦的consul代理服務(wù)器。
bootstrap-expect:是集群?jiǎn)?dòng)條件,指當(dāng)服務(wù)器端模式(Server模式)的代理達(dá)到這個(gè)數(shù)目后,才開始運(yùn)行。
data-dir:是存放數(shù)據(jù)中心數(shù)據(jù)的,該目錄必須是穩(wěn)定的,系統(tǒng)重啟后也繼續(xù)存在的。
datacenter:當(dāng)前agent的中心數(shù)據(jù)的名稱,默認(rèn)是dc1。
node:節(jié)點(diǎn)在集群中的名稱,在一個(gè)集群中必須是唯一的,默認(rèn)是該節(jié)點(diǎn)的主機(jī)名(代表一個(gè)機(jī)器)。
client:本地ip地址,這里使用 0.0.0.0 ,就表示這個(gè)服務(wù)器所有IP都可以,即當(dāng)這臺(tái)電腦有倆ip,192.168.1.111和192.168.1.112,那么通過這倆IP都可以訪問到這臺(tái)機(jī)器的consul代理服務(wù)器。
運(yùn)行該命令,如下圖所示:
可以看到,我們的Consul代理服務(wù)已經(jīng)成功運(yùn)行了。
現(xiàn)在,我們?cè)谌チ硪慌_(tái)電腦,打開cmd窗口,運(yùn)行如下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
可以看到,我們?cè)诿钚凶詈竺孀芳恿艘粋€(gè)join 192.168.80.111;通過這個(gè)命令,我們把這臺(tái)電腦的代理服務(wù)器成功的加入到了上文中的consul集群。
服務(wù)注冊(cè)與發(fā)現(xiàn)
Consul的服務(wù)注冊(cè)
首先,我們創(chuàng)建一個(gè)WebAPI,這里為使用了Core框架創(chuàng)建了一個(gè)Web API,為了方便測(cè)試,我就直接拿本地的VisualStudio啟動(dòng)測(cè)試了。
創(chuàng)建WebAPI后,我們?cè)贜uget中查找Consul的Net版本類庫。
在Nuget中搜索Consul,然后選中下圖中的選項(xiàng)進(jìn)行安裝。
然后,我們?cè)赟tartup文件中,增加一個(gè)函數(shù),如下:
public static void RegisterConsul() { var consulClient = new ConsulClient(p => { p.Address = new Uri($"http://127.0.0.1:8500"); });//請(qǐng)求注冊(cè)的 Consul 地址 //這里的這個(gè)ip 就是本機(jī)的ip,這個(gè)端口8500 這個(gè)是默認(rèn)注冊(cè)服務(wù)端口 var httpCheck = new AgentServiceCheck() { DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服務(wù)啟動(dòng)多久后注冊(cè) Interval = TimeSpan.FromSeconds(10),//間隔固定的時(shí)間訪問一次,https://localhost:44308/api/Health HTTP = $"https://localhost:44308/api/Health",//健康檢查地址 44308是visualstudio啟動(dòng)的端口 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();//注冊(cè)服務(wù) //consulClient.Agent.ServiceDeregister(registration.ID).Wait();//registration.ID是guid //當(dāng)服務(wù)停止時(shí)需要取消服務(wù)注冊(cè),不然,下次啟動(dòng)服務(wù)時(shí),會(huì)再注冊(cè)一個(gè)服務(wù)。 //但是,如果該服務(wù)長(zhǎng)期不啟動(dòng),那consul會(huì)自動(dòng)刪除這個(gè)服務(wù),大約2,3分鐘就會(huì)刪了 }
然后在Configure中調(diào)用這個(gè)方法,這樣,當(dāng)我們調(diào)試或運(yùn)行這個(gè)項(xiàng)目時(shí),就會(huì)自動(dòng)將這個(gè)Webapi注冊(cè)到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();//注冊(cè)本服務(wù)到consul集群 }
服務(wù)注冊(cè)完后,可以訪問本地?cái)?shù)據(jù)中心的網(wǎng)站【http://127.0.0.1:8500/ui/dc1/services】來查看注冊(cè)服務(wù)的狀態(tài)。
Consul服務(wù)發(fā)現(xiàn)
服務(wù)注冊(cè)完成后,我們?cè)賱?chuàng)建一個(gè)控制臺(tái)項(xiàng)目來進(jìn)行服務(wù)發(fā)現(xiàn)。
創(chuàng)建完成項(xiàng)目后,也需要引用consul類庫,同服務(wù)端一樣在Nuget中搜索。
編寫代碼如下:
static void Main(string[] args) { var consulClient = new ConsulClient(x => x.Address = new Uri($"http://192.168.1.178:8500"));//請(qǐng)求注冊(cè)的 Consul 地址 var ret = consulClient.Agent.Services(); var allServer = ret.GetAwaiter().GetResult(); //這個(gè)是個(gè)dictionary的返回值,他的key是string類型,就是8500/ui上services的instance的id var allServerDic = allServer.Response; var test1 = allServerDic.First(); string name = test1.Value.Service;//服務(wù)名,就是注冊(cè)的那個(gè)test1 string serverAddress = test1.Value.Address; int serverPort = test1.Value.Port; Console.WriteLine($"serverAddress:{serverAddress}==serverPort{serverPort}"); //我們可以在客戶端啟動(dòng)的時(shí)候,調(diào)用一下consul來查找服務(wù) //比如,我們可以在服務(wù)集合里查找 服務(wù)名叫test1的服務(wù) 然后在調(diào)用它 //這樣,當(dāng)服務(wù)器改變了test1的ip和端口,我們依然可以在集群里找他test1新的ip和端口了 Console.ReadKey(); }
運(yùn)行結(jié)果如下:
可以看到,我們已經(jīng)成功調(diào)用了Consul,也成功的獲取到了服務(wù)信息。
其實(shí)Consul除了服務(wù)注冊(cè)與查詢,還可以進(jìn)行Key-Value存儲(chǔ),也就是說,這個(gè)是一個(gè)分布式Key-Value存儲(chǔ)集群。
Key-Value存儲(chǔ)的用法在Github已經(jīng)有例子了,網(wǎng)址:https://github.com/PlayFab/consuldotnet。
C#使用Consul進(jìn)行服務(wù)注冊(cè)與發(fā)現(xiàn)就講完了。
代碼已經(jīng)傳到Github上了,歡迎大家下載。
Github地址:https://github.com/kiba518/KibaConsul
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
上一篇:Unity3D實(shí)現(xiàn)射線使物體移動(dòng)
欄 目:C#教程
下一篇:unity3D實(shí)現(xiàn)三維物體跟隨鼠標(biāo)
本文標(biāo)題:C#使用Consul集群進(jìn)行服務(wù)注冊(cè)與發(fā)現(xiàn)
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/4576.html
您可能感興趣的文章
- 01-10C#使用Dispose模式實(shí)現(xiàn)手動(dòng)對(duì)資源的釋放
- 01-10C#3.0使用EventLog類寫Windows事件日志的方法
- 01-10C#使用windows服務(wù)開啟應(yīng)用程序的方法
- 01-10c# ArrayList的使用方法小總結(jié)
- 01-10C#使用ADO.Net部件來訪問Access數(shù)據(jù)庫的方法
- 01-10C#使用Mutex簡(jiǎn)單實(shí)現(xiàn)程序單實(shí)例運(yùn)行的方法
- 01-10使用Nopcommerce為商城添加滿XX減XX優(yōu)惠券功能
- 01-10C#中yield用法使用說明
- 01-10C#編程和Visual Studio使用技巧(下)
- 01-10C#編程和Visual Studio使用技巧(上)


閱讀排行
- 1C語言 while語句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻 器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 04-02jquery與jsp,用jquery
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10delphi制作wav文件的方法
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?