網站首頁 編程語言 正文
1.服務注冊與發現(Service Discovery)
- 服務注冊:我們通過在每個服務實例寫入注冊代碼,實例在啟動的時候會先去注冊中心(例如Consul、ZooKeeper、etcd、Eureka)注冊一下,那么客戶端通過注冊中心可以知道每個服務實例的地址,端口號,健康狀態等等信息,也可以通過注冊中心刪除服務實例。這里注冊中心相當于是負責維護服務實例的管控中心。
- 服務發現:服務實例在注冊中心注冊之后,客戶端通過注冊中心可以了解這些服務實例運行狀況。
2.Consul
如果要實現服務注冊與發現,需要一個注冊中心,這里主要介紹是Consul。
Consul官網:https://www.consul.io/,它主要功能有:服務注冊與發現、健康檢查、Key/Value、多數據中心。
如果在Windows上部署Consul,在consul.exe目錄下執行consul.exe agent -dev
命令行即可。
3.Asp.Net Core向Consul注冊服務實例
Asp.Net Core向Consul注冊服務實例調用過程如下圖所示:
Asp.Net Core向Consul注冊服務實例需要在Gateway項目中引用Consul支持的NuGet軟件包,安裝命令如下:
Install-Package Ocelot.Provider.Consul
然后將以下內容添加到您的ConfigureServices方法中:
services.AddOcelot().AddConsul();
在Ocelot服務發現項目示例中,通過APIGateway項目GlobalConfiguration選項可以配置服務注冊與發現,文件配置具體代碼如下:
{ "Routes": [ { "UseServiceDiscovery": true, "DownstreamPathTemplate": "/{url}", "DownstreamScheme": "http", "ServiceName": "MyService", "LoadBalancerOptions": { "Type": "RoundRobin" }, "UpstreamPathTemplate": "/{url}", "UpstreamHttpMethod": [ "Get" ], "ReRoutesCaseSensitive": false } ], "GlobalConfiguration": { //服務發現配置 "ServiceDiscoveryProvider": { //注冊中心Consul地址 "Host": "192.168.113.128", //注冊中心Consul端口號 "Port": 8500, "Type": "Consul", //以毫秒為單位,告訴Ocelot多久調用一次Consul來更改服務配置。 "PollingInterval": 100, //如果你有在Consul上配置key/value,則在這里輸入配置key。 "ConfigurationKey": "MyService_AB" } } }
ServiceDiscoveryProvider選項說明:
- Host:注冊中心Consul地址。
- Port:注冊中心Consul端口號。
- Type:注冊中心類型。
- PollingInterval:以毫秒為單位,告訴Ocelot多久調用一次Consul來更改服務配置。
- ConfigurationKey:如果你有在Consul上配置key/value,則在這里輸入配置key。
4.項目演示
4.1APIGateway項目
ConfigureServices添加Ocelot、Consul注入:
services.AddOcelot().AddConsul();
Configure添加使用Ocelot:
app.UseOcelot().Wait();
服務發現配置如Ocelot服務發現項目示例一樣。
4.2Common項目
先安裝Consul的NuGet軟件包,安裝命令如下:
Install-Package Consul
在該項目添加一個AppExtensions擴展類,用來對服務APIServiceA、APIServiceB項目在Consul注冊實例,為了展示效果,具體代碼稍作修改如下:
public static class AppExtensions { public static IServiceCollection AddConsulConfig(this IServiceCollection services, IConfiguration configuration) { services.AddSingleton(p => new ConsulClient(consulConfig => { var address = configuration.GetValue ("Consul:Host"); consulConfig.Address = new Uri(address); })); return services; } public static IApplicationBuilder UseConsul(this IApplicationBuilder app, string host = null, string port = null) { //獲取consul客戶端實例 var consulClient = app.ApplicationServices.GetRequiredService (); var logger = app.ApplicationServices.GetRequiredService ().CreateLogger("AppExtensions"); var lifetime = app.ApplicationServices.GetRequiredService (); if (!(app.Properties["server.Features"] is FeatureCollection features)) return app; //var addresses = features.Get (); //var address = addresses.Addresses.FirstOrDefault(); //if (address == null) //{ // return app; //} var address = host + ":" + port; if (string.IsNullOrWhiteSpace(host) || string.IsNullOrWhiteSpace(port)) { Console.WriteLine($"host或者port為空!"); return app; } Console.WriteLine($"address={address}"); var uri = new Uri(address); Console.WriteLine($"host={uri.Host},port={uri.Port}"); var registration = new AgentServiceRegistration() { ID = $"MyService-{uri.Port}", Name = "MyService", Address = $"{uri.Host}", Port = uri.Port, Check = new AgentServiceCheck() { DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服務啟動多久后注冊 Interval = TimeSpan.FromSeconds(10),//健康檢查時間間隔 HTTP = $"{address}/HealthCheck",//健康檢查地址 Timeout = TimeSpan.FromSeconds(5)//超時時間 } }; logger.LogInformation("Registering with Consul"); logger.LogInformation($"Consul RegistrationID:{registration.ID}"); //注銷 consulClient.Agent.ServiceDeregister(registration.ID).ConfigureAwait(true); //注冊 consulClient.Agent.ServiceRegister(registration).ConfigureAwait(true); //應用程序關閉時候 lifetime.ApplicationStopping.Register(() => { //正在注銷 logger.LogInformation("Unregistering from Consul"); consulClient.Agent.ServiceDeregister(registration.ID).ConfigureAwait(true); }); //每個服務都需要提供一個用于健康檢查的接口,該接口不具備業務功能。服務注冊時把這個接口的地址也告訴注冊中心,注冊中心會定時調用這個接口來檢測服務是否正常,如果不正常,則將它移除,這樣就保證了服務的可用性。 app.Map("/HealthCheck", s => { s.Run(async context => { await context.Response.WriteAsync("ok"); }); }); return app; } }
4.3APIServiceA項目
項目添加一個Get方法,對應APIGateway項目的路由上下游配置,具體代碼如下:
[Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { // GET api/values [HttpGet] public ActionResult> Get() { var port = Request.Host.Port; return new string[] { "value1", "value2", port.Value.ToString() }; } }
appsettings.json配置加入Consul地址:
"Consul": { "Host": "http://192.168.113.128:8500" }
4.4APIServiceB項目
項目添加一個Get方法,對應APIGateway項目的路由上下游配置,具體代碼如下:
[Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { // GET api/values [HttpGet] public ActionResult> Get() { var port = Request.Host.Port; return new string[] { "value3", "value4", port.Value.ToString() }; } }
appsettings.json配置加入Consul地址:
"Consul": { "Host": "http://192.168.113.128:8500" }
4.5項目運行
在APIServiceA、APIServiceB項目的ConfigureServices添加Consul配置:
services.AddConsulConfig(Configuration);
在Configure添加Consul服務注冊:
APIServiceA:app.UseConsul("http://172.168.18.73", "9999"); APIServiceB:app.UseConsul("http://172.168.18.73", "9998");
把APIGateway、APIServiceA、APIServiceB三個項目部署到IIS上:
三個項目運行起來后,通過瀏覽器Consul客戶端可以看到MyService節點服務情況:
點擊打開MyService節點可以看到注冊到Consul的APIServiceA、APIServiceB服務狀況:
如果把APIServiceB服務實例站點停掉:
通過Consul客戶端會看到APIServiceB服務實例已經被剔除了:
如果輸入CTRL+C把集群中某一個Consul服務關閉,那么集群會重新選舉一個新的leader,負責處理所有服務實例的查詢和事務:
原文鏈接:https://www.cnblogs.com/wzk153/p/14109705.html
相關推薦
- 2022-07-16 如何編譯omx-bellagio以及ffmpeg插件
- 2023-03-29 C語言交換奇偶位與offsetof宏的實現方法_C 語言
- 2022-06-19 Go獲取兩個時間點時間差的具體實現_Golang
- 2022-08-28 keil5仿真相關配置,解決相關bug
- 2022-06-04 sentinel支持的redis高可用集群配置詳解_Redis
- 2022-09-02 Oracle11g調整SGA方法詳解_oracle
- 2023-04-06 C#中的那些警告該如何去除(完全去除C#警告)_C#教程
- 2022-08-19 vscode遠程免密登入Linux服務器的配置方法_Linux
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支