1、什么是服務注冊中心?
在學習服務注冊與發現時,我們要先搞明白到底什么是服務注冊與發現。
在這里我舉一個生活中非常普遍的例子——網購來簡單說明,網購在我們日常生活中已經是非常普遍了,其實網購中的(商家—菜鳥驛站—買家),就組成了一個非常簡單的注冊發現邏輯。在我們購買商品之后,需要拿到這件商品,如果是普通的點對點服務,商家直接將商品快遞給買家,如果買家臨時有事不在家,這個時候將會收貨失敗。
當引入注冊中心—菜鳥驛站之后,商家發貨后只需要將商品發送給菜鳥驛站(服務注冊),買家在合適的時間通過快遞號或者掃碼去菜鳥驛站拿取自己的商品(服務發現),在這個環節中,菜鳥驛站只負責商品的收與發,這樣就構成了一個簡單的服務發現邏輯。
2、為什么要使用服務注冊中心?
1、解耦:
服務消費者和服務提供者之間完全解耦。就如同上面的例子:買家不用去關心賣家到底發什么快遞,只要我去快遞驛站能拿到商品就OK。
2、擴展:
服務消費者和服務提供者增加和刪除新的服務時,對於雙方沒有任何影響。比如:買家買了多個不同的商品,這時買家也只需要根據不同的取件憑據去菜鳥驛站拿取對應的商品就OK。
3、不同的服務注冊中心組件
zookeeper
ZooKeeper是一個分布式的,開放源碼的分布式應用程序協調服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的重要組件。它是一個為分布式應用提供一致性服務的軟件,提供的功能包括:配置維護、域名服務、分布式同步、組服務等。ZooKeeper的目標就是封裝好復雜易出錯的關鍵服務,將簡單易用的接口和性能高效、功能穩定的系統提供給用戶。ZooKeeper包含一個簡單的原語集,提供Java和C的接口。
consul
Consul 是 HashiCorp 公司推出的開源產品,用於實現分布式系統的服務發現、服務隔離、服務配置,這些功能中的每一個都可以根據需要單獨使用,也可以同時使用所有功能。Consul 官網目前主要推 Consul 在服務網格中的使用。
etcd
etcd是CoreOS團隊於2013年6月發起的開源項目,它的目標是構建一個高可用的分布式鍵值(key-value)數據庫。etcd內部采用raft
協議作為一致性算法,etcd基於Go語言實現。
eureka
eureka注冊中心已經閉源,不建議在家學習使用。
Consul是一個用來實現分布式系統的服務發現與配置的開源工具。是由go語言開發。他主要由多個組成部分:
-
服務發現:客戶端通過Consul提供服務,類似於API、MySQL、或者其他客戶端可以使用Consul發現服務的提供者。使用類似DNS或者HTTP,應用程序和可以很輕松的發現他們依賴的服務。
-
檢查健康:Consul客戶端可以提供與給定服務相關的健康檢查(Web服務器返回200 ok)或者本地節點(“內存利用率低於90%”)。這些信息可以監控集群的運行情況,並且使訪問遠離不健康的主機組件。
-
鍵值對存儲:應用程序可以使用Cousul的層級鍵值對。
-
多數據中心:Consul有開箱及用的多數據中心。
5、如何在asp.net core中使用Consul
概念性的內容已經講的差不多了,下面我們來看看如何在asp.net core+windows下使用Consul。
5.1、下載Consul
官網地址: https://www.consul.io/
下載地址: https://releases.hashicorp.com/consul/1.7.2/ 或 https://www.consul.io/downloads.html
5.2、啟動Consul
consul.exe agent -dev
參數介紹:
- Version:consul版本
- Node ID:consul當前啟動的節點ID
- Node name:consul當前啟動的節點名稱,默認當前電腦名稱
- Datacenter:數據中心
- Service:consul的啟動模式,true表示服務端模式,false表示客戶端模式
- Client Addr:客戶端連接地址,支持HTTP、HTTPS、GRPC、DNS,默認使用HTTP
- Cluster Addr:集群地址,就是Server模式下的啟動方式
5.3、編碼
5.3.1、創建兩個asp.net core webapi項目,並分別引用Consul的包。
5.3.2、編寫服務提供者代碼
在服務提供項目(ConsulService)的Startup類的Configure方法內編寫如下代碼:
1 // 創建Consul的客戶端連接 2 var consulClient = new ConsulClient(configuration => 3 { 4 // Consul的連接地址 5 configuration.Address = new Uri("http://127.0.0.1:8500"); 6 }); 7 // 創建Consul的服務注冊信息 8 var registration = new AgentServiceRegistration() 9 { 10 // 服務ID 11 ID = Guid.NewGuid().ToString(), 12 // 服務名稱 13 Name = "demoService", 14 // 服務連接地址 15 Address = "https://localhost", 16 // 端口 17 Port = 5001 18 // AgentServiceRegistration對象還有一些其他屬性,后面有機會再了解 19 }; 20 // 注冊服務 21 consulClient.Agent.ServiceRegister(registration);
然后啟動項目:
項目啟動成功,我們訪問Consul的可視化web頁面(地址默認是8500端口),看服務是否注冊成功:
從上面的截圖可以看到,我們剛剛注冊的demoService服務已經注冊成功了。
5.3.3、編寫服務消費者代碼
在服務消費者項目中添加一個Service文件夾,新增一個服務消費的接口然后實現這個接口:
1 public interface IDemoService 2 { 3 Task<string> GetDemoService(); 4 } 5 public class DemoService : IDemoService 6 { 7 private readonly IHttpClientFactory httpClientFactory; 8 9 public DemoService(IHttpClientFactory httpClientFactory) 10 { 11 this.httpClientFactory = httpClientFactory; 12 } 13 14 public async Task<string> GetDemoService() 15 { 16 var res = ""; 17 // 創建consul連接對象 18 var consulClient = new Consul.ConsulClient(configuare => 19 { 20 // Consul的連接地址 21 configuare.Address = new Uri("http://127.0.0.1:8500"); 22 }); 23 // 根據剛才注冊的服務名稱獲取對應的服務 24 var queryResult = await consulClient.Catalog.Service("demoService"); 25 // 服務連接地址 26 var serviceUrls = new List<string>(); 27 // 遍歷獲取到的服務列表 28 foreach (var service in queryResult.Response) 29 { 30 // 拼接連接地址 31 serviceUrls.Add(service.ServiceAddress + ":" + service.ServicePort); 32 } 33 HttpClient httpClient = httpClientFactory.CreateClient(); 34 HttpResponseMessage response = await httpClient.GetAsync(serviceUrls[0] + "/api/Home/"); 35 if (response.StatusCode == HttpStatusCode.OK) 36 { 37 res = await response.Content.ReadAsStringAsync(); 38 } 39 return res; 40 } 41 }
在控制器調用這個服務:
1 private readonly ILogger<HomeController> _logger; 2 private readonly IDemoService _demoService; 3 4 public HomeController(ILogger<HomeController> logger, IDemoService demoService) 5 { 6 _logger = logger; 7 _demoService = demoService; 8 } 9 10 [HttpGet] 11 public Task<string> Get() 12 { 13 return _demoService.GetDemoService(); 14 }
注意,記得在Startup類中的ConfigureService方法中注入上面的服務接口與類,具體為什么要注入應該不用我多說了。
1 services.AddScoped<IDemoService, DemoService>();
最后,我們啟動消費者項目,並請求對應接口看看效果,很顯然,服務已經請求成功。
這篇文章暫時就到這里,上面就是.net core對Consul最簡單的應用。隨着學習的深入,后面會有相應的學習筆記記錄。
因為本人也是處於探索階段,上面所寫的也僅僅是一些學習筆記,所以一些理解可能不夠准確,希望所寫的一些內容出現錯誤大家能給予包容和指正。