Asp.Net?Core使用Ocelot結(jié)合Consul實(shí)現(xiàn)服務(wù)注冊(cè)和發(fā)現(xiàn)
1.服務(wù)注冊(cè)與發(fā)現(xiàn)(Service Discovery)
- 服務(wù)注冊(cè):我們通過在每個(gè)服務(wù)實(shí)例寫入注冊(cè)代碼,實(shí)例在啟動(dòng)的時(shí)候會(huì)先去注冊(cè)中心(例如Consul、ZooKeeper、etcd、Eureka)注冊(cè)一下,那么客戶端通過注冊(cè)中心可以知道每個(gè)服務(wù)實(shí)例的地址,端口號(hào),健康狀態(tài)等等信息,也可以通過注冊(cè)中心刪除服務(wù)實(shí)例。這里注冊(cè)中心相當(dāng)于是負(fù)責(zé)維護(hù)服務(wù)實(shí)例的管控中心。
- 服務(wù)發(fā)現(xiàn):服務(wù)實(shí)例在注冊(cè)中心注冊(cè)之后,客戶端通過注冊(cè)中心可以了解這些服務(wù)實(shí)例運(yùn)行狀況。
2.Consul
如果要實(shí)現(xiàn)服務(wù)注冊(cè)與發(fā)現(xiàn),需要一個(gè)注冊(cè)中心,這里主要介紹是Consul。
Consul官網(wǎng):https://www.consul.io/,它主要功能有:服務(wù)注冊(cè)與發(fā)現(xiàn)、健康檢查、Key/Value、多數(shù)據(jù)中心。
如果在Windows上部署Consul,在consul.exe目錄下執(zhí)行consul.exe agent -dev命令行即可。
3.Asp.Net Core向Consul注冊(cè)服務(wù)實(shí)例
Asp.Net Core向Consul注冊(cè)服務(wù)實(shí)例調(diào)用過程如下圖所示:

Asp.Net Core向Consul注冊(cè)服務(wù)實(shí)例需要在Gateway項(xiàng)目中引用Consul支持的NuGet軟件包,安裝命令如下:
Install-Package Ocelot.Provider.Consul
然后將以下內(nèi)容添加到您的ConfigureServices方法中:
services.AddOcelot().AddConsul();
在Ocelot服務(wù)發(fā)現(xiàn)項(xiàng)目示例中,通過APIGateway項(xiàng)目GlobalConfiguration選項(xiàng)可以配置服務(wù)注冊(cè)與發(fā)現(xiàn),文件配置具體代碼如下:
{
"Routes": [
{
"UseServiceDiscovery": true,
"DownstreamPathTemplate": "/{url}",
"DownstreamScheme": "http",
"ServiceName": "MyService",
"LoadBalancerOptions": {
"Type": "RoundRobin"
},
"UpstreamPathTemplate": "/{url}",
"UpstreamHttpMethod": [ "Get" ],
"ReRoutesCaseSensitive": false
}
],
"GlobalConfiguration": {
//服務(wù)發(fā)現(xiàn)配置
"ServiceDiscoveryProvider": {
//注冊(cè)中心Consul地址
"Host": "192.168.113.128",
//注冊(cè)中心Consul端口號(hào)
"Port": 8500,
"Type": "Consul",
//以毫秒為單位,告訴Ocelot多久調(diào)用一次Consul來更改服務(wù)配置。
"PollingInterval": 100,
//如果你有在Consul上配置key/value,則在這里輸入配置key。
"ConfigurationKey": "MyService_AB"
}
}
}ServiceDiscoveryProvider選項(xiàng)說明:
- Host:注冊(cè)中心Consul地址。
- Port:注冊(cè)中心Consul端口號(hào)。
- Type:注冊(cè)中心類型。
- PollingInterval:以毫秒為單位,告訴Ocelot多久調(diào)用一次Consul來更改服務(wù)配置。
- ConfigurationKey:如果你有在Consul上配置key/value,則在這里輸入配置key。
4.項(xiàng)目演示
4.1APIGateway項(xiàng)目
ConfigureServices添加Ocelot、Consul注入:
services.AddOcelot().AddConsul();
Configure添加使用Ocelot:
app.UseOcelot().Wait();
服務(wù)發(fā)現(xiàn)配置如Ocelot服務(wù)發(fā)現(xiàn)項(xiàng)目示例一樣。
4.2Common項(xiàng)目
先安裝Consul的NuGet軟件包,安裝命令如下:
Install-Package Consul
在該項(xiàng)目添加一個(gè)AppExtensions擴(kuò)展類,用來對(duì)服務(wù)APIServiceA、APIServiceB項(xiàng)目在Consul注冊(cè)實(shí)例,為了展示效果,具體代碼稍作修改如下:
public static class AppExtensions
{
public static IServiceCollection AddConsulConfig(this IServiceCollection services, IConfiguration configuration)
{
services.AddSingleton<IConsulClient, ConsulClient>(p => new ConsulClient(consulConfig =>
{
var address = configuration.GetValue<string>("Consul:Host");
consulConfig.Address = new Uri(address);
}));
return services;
}
public static IApplicationBuilder UseConsul(this IApplicationBuilder app, string host = null, string port = null)
{
//獲取consul客戶端實(shí)例
var consulClient = app.ApplicationServices.GetRequiredService<IConsulClient>();
var logger = app.ApplicationServices.GetRequiredService<ILoggerFactory>().CreateLogger("AppExtensions");
var lifetime = app.ApplicationServices.GetRequiredService<IApplicationLifetime>();
if (!(app.Properties["server.Features"] is FeatureCollection features)) return app;
//var addresses = features.Get<IServerAddressesFeature>();
//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),//服務(wù)啟動(dòng)多久后注冊(cè)
Interval = TimeSpan.FromSeconds(10),//健康檢查時(shí)間間隔
HTTP = $"{address}/HealthCheck",//健康檢查地址
Timeout = TimeSpan.FromSeconds(5)//超時(shí)時(shí)間
}
};
logger.LogInformation("Registering with Consul");
logger.LogInformation($"Consul RegistrationID:{registration.ID}");
//注銷
consulClient.Agent.ServiceDeregister(registration.ID).ConfigureAwait(true);
//注冊(cè)
consulClient.Agent.ServiceRegister(registration).ConfigureAwait(true);
//應(yīng)用程序關(guān)閉時(shí)候
lifetime.ApplicationStopping.Register(() =>
{
//正在注銷
logger.LogInformation("Unregistering from Consul");
consulClient.Agent.ServiceDeregister(registration.ID).ConfigureAwait(true);
});
//每個(gè)服務(wù)都需要提供一個(gè)用于健康檢查的接口,該接口不具備業(yè)務(wù)功能。服務(wù)注冊(cè)時(shí)把這個(gè)接口的地址也告訴注冊(cè)中心,注冊(cè)中心會(huì)定時(shí)調(diào)用這個(gè)接口來檢測(cè)服務(wù)是否正常,如果不正常,則將它移除,這樣就保證了服務(wù)的可用性。
app.Map("/HealthCheck", s =>
{
s.Run(async context =>
{
await context.Response.WriteAsync("ok");
});
});
return app;
}
}4.3APIServiceA項(xiàng)目
項(xiàng)目添加一個(gè)Get方法,對(duì)應(yīng)APIGateway項(xiàng)目的路由上下游配置,具體代碼如下:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> 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項(xiàng)目
項(xiàng)目添加一個(gè)Get方法,對(duì)應(yīng)APIGateway項(xiàng)目的路由上下游配置,具體代碼如下:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> 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項(xiàng)目運(yùn)行
在APIServiceA、APIServiceB項(xiàng)目的ConfigureServices添加Consul配置:
services.AddConsulConfig(Configuration);
在Configure添加Consul服務(wù)注冊(cè):
APIServiceA:app.UseConsul("http://172.168.18.73", "9999");
APIServiceB:app.UseConsul("http://172.168.18.73", "9998");把APIGateway、APIServiceA、APIServiceB三個(gè)項(xiàng)目部署到IIS上:

三個(gè)項(xiàng)目運(yùn)行起來后,通過瀏覽器Consul客戶端可以看到MyService節(jié)點(diǎn)服務(wù)情況:

點(diǎn)擊打開MyService節(jié)點(diǎn)可以看到注冊(cè)到Consul的APIServiceA、APIServiceB服務(wù)狀況:

如果把APIServiceB服務(wù)實(shí)例站點(diǎn)停掉:

通過Consul客戶端會(huì)看到APIServiceB服務(wù)實(shí)例已經(jīng)被剔除了:

如果輸入CTRL+C把集群中某一個(gè)Consul服務(wù)關(guān)閉,那么集群會(huì)重新選舉一個(gè)新的leader,負(fù)責(zé)處理所有服務(wù)實(shí)例的查詢和事務(wù):


到此這篇關(guān)于Asp.Net Core使用Ocelot結(jié)合Consul實(shí)現(xiàn)服務(wù)注冊(cè)和發(fā)現(xiàn)的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
c#將Excel數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫(kù)的實(shí)現(xiàn)代碼
這篇文章主要介紹了c#將Excel數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫(kù)的實(shí)現(xiàn)代碼,有需要的朋友可以參考一下2013-12-12
ASP.NET AJAX 4.0的模版編程(Template Programming)介紹
不過當(dāng)我評(píng)估ASP.NET AJAX 4.0的時(shí)候,我確實(shí)被它的特征給震住了。新的特征完全專注于瀏覽器技術(shù),比如XHTML和javascript。 我非常欽佩ASP.NET AJAX小組。2009-07-07
asp.net下檢測(cè)遠(yuǎn)程URL是否存在的三種方法
檢測(cè)遠(yuǎn)程URL是否存在的三種方法,需要的朋友可以參考下。2009-12-12
.Net?Core?使用?TagProvider?與?Enricher?豐富日志的操作代碼
這篇文章主要介紹了.Net?Core?使用?TagProvider?與?Enricher?豐富日志的操作,本文通過示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2024-03-03
Asp.net控制Tomcat啟動(dòng)關(guān)閉的實(shí)現(xiàn)方法
近日有個(gè)項(xiàng)目客戶要求能自己配置相關(guān)權(quán)限。由于歷史原因這個(gè)項(xiàng)目采用的是公司以前的權(quán)限系統(tǒng)2012-01-01
Asp.Net 生成靜態(tài)頁(yè)并實(shí)現(xiàn)分頁(yè)效果
Asp.Net 生成靜態(tài)頁(yè)并實(shí)現(xiàn)分頁(yè)效果的代碼,需要的朋友可以參考下。2010-04-04
VS2012實(shí)現(xiàn)簡(jiǎn)單登錄界面
這篇文章主要為大家詳細(xì)介紹了VS2012實(shí)現(xiàn)簡(jiǎn)單登錄界面,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06

