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最簡單的應用。隨著學習的深入,後面會有相應的學習筆記記錄。
因為本人也是處於探索階段,上面所寫的也僅僅是一些學習筆記,所以一些理解可能不夠準確,希望所寫的一些內容出現錯誤大家能給予包容和指正。