前言
在上一篇文章【.Net Core微服務入門全記錄(一)-項目搭建】說到服務的彈性伸縮,就需要有一種機制來實現(xiàn)。這種機制就是服務注冊和發(fā)現(xiàn)。當然,這不是必需的。如果您的服務實例很少且穩(wěn)定,則無需使用服務注冊和發(fā)現(xiàn)。
服務注冊和發(fā)現(xiàn)
通過服務注冊和發(fā)現(xiàn),客戶端不需要配置每個服務實例的地址core 注冊機,而是從注冊中心獲取。注冊中心如何保證每個地址的可用性,如果一個實例掛了怎么辦?掛機的實例原則上不應該被客戶端獲取,所以需要提一下:健康檢查。
常見的注冊表是 , , etcd 。
官網(wǎng):主要功能包括服務注冊與發(fā)現(xiàn)、健康檢查、KV存儲、多數(shù)據(jù)中心等。
已成功運行。
服務注冊
封裝在這個類庫中的api操作方便我們直接使用。當然,自己寫http調(diào)用的接口也不是不可能。. . 接口說明:
。CS:
public static class ConsulHelper
{
///
/// 服務注冊到consul
///
///
///
public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IConfiguration configuration, IHostApplicationLifetime lifetime)
{
var consulClient = new ConsulClient(c =>
{
//consul地址
c.Address = new Uri(configuration["ConsulSetting:ConsulAddress"]);
});
var registration = new AgentServiceRegistration()
{
ID = Guid.NewGuid().ToString(),//服務實例唯一標識
Name = configuration["ConsulSetting:ServiceName"],//服務名
Address = configuration["ConsulSetting:ServiceIP"], //服務IP
Port = int.Parse(configuration["ConsulSetting:ServicePort"]),//服務端口 因為要運行多個實例,端口不能在appsettings.json里配置,在docker容器運行時傳入
Check = new AgentServiceCheck()
{
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服務啟動多久后注冊
Interval = TimeSpan.FromSeconds(10),//健康檢查時間間隔
HTTP = $"http://{configuration["ConsulSetting:ServiceIP"]}:{configuration["ConsulSetting:ServicePort"]}{configuration["ConsulSetting:ServiceHealthCheck"]}",//健康檢查地址
Timeout = TimeSpan.FromSeconds(5)//超時時間
}
};
//服務注冊
consulClient.Agent.ServiceRegister(registration).Wait();
//應用程序終止時,取消注冊
lifetime.ApplicationStopping.Register(() =>

{
consulClient.Agent.ServiceDeregister(registration.ID).Wait();
});
return app;
}
}
復制
.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConsulSetting": {
"ServiceName": "OrderService",
"ServiceIP": "localhost",
"ServiceHealthCheck": "/healthcheck",
"ConsulAddress": "http://host.docker.internal:8500"http://注意,docker容器內(nèi)部無法使用localhost訪問宿主機器,如果是控制臺啟動的話就用localhost
}
}
復制
。CS:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
//服務注冊
app.RegisterConsul(Configuration, lifetime);
}
}
復制
。CS:
[Route("[controller]")]
[ApiController]
public class OrdersController : ControllerBase
{
private readonly ILogger _logger;
private readonly IConfiguration _configuration;
public OrdersController(ILogger logger, IConfiguration configuration)
{
_logger = logger;
_configuration = configuration;
}
[HttpGet]
public IActionResult Get()
{
string result = $"【訂單服務】{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}——" +
$"{Request.HttpContext.Connection.LocalIpAddress}:{_configuration["ConsulSetting:ServicePort"]}";
return Ok(result);
}
}
復制
r.cs:
[Route("[controller]")]
[ApiController]
public class HealthCheckController : ControllerBase
{
///
/// 健康檢查接口
///
///
[HttpGet]
public IActionResult Get()
{
return Ok();
}
}
復制
至此,服務注冊、注銷、健康檢查等功能的代碼編寫已經(jīng)完成。
運行服務
繼續(xù)運行服務實例,如果不習慣可以用控制臺啟動。--:參數(shù)是傳入容器的端口信息。
docker build -t orderapi:1.0 -f ./Order.API/Dockerfile .
docker run -d -p 9060:80 --name orderservice orderapi:1.0 --ConsulSetting:ServicePort="9060"
docker run -d -p 9061:80 --name orderservice1 orderapi:1.0 --ConsulSetting:ServicePort="9061"
docker run -d -p 9062:80 --name orderservice2 orderapi:1.0 --ConsulSetting:ServicePort="9062"
docker build -t productapi:1.0 -f ./Product.API/Dockerfile .
docker run -d -p 9050:80 --name productservice productapi:1.0 --ConsulSetting:ServicePort="9050"
docker run -d -p 9051:80 --name productservice1 productapi:1.0 --ConsulSetting:ServicePort="9051"
docker run -d -p 9052:80 --name productservice2 productapi:1.0 --ConsulSetting:ServicePort="9052"
復制
到目前為止,所有 6 個服務器實例都在運行并成功注冊。
只需停止 2 項服務:
可以看到停止的服務已經(jīng)被刪除了。請注意,當我們停止程序時,它會被主動調(diào)用以刪除。
//應用程序終止時,取消注冊
lifetime.ApplicationStopping.Register(() =>
{
consulClient.Agent.ServiceDeregister(registration.ID).Wait();
});
復制
當然,如果程序發(fā)生異常core 注冊機,健康檢查未能正確響應,也會被移除core 注冊機,有一點區(qū)別。
至此,注冊、發(fā)現(xiàn)、健康檢查功能就完成了。下一步是考慮客戶端如何獲取這些服務實例的地址。
代碼放置在:
未完待續(xù)...