前言
在上一篇文章【.Net Core微服务入门全记录(一)-项目搭建】说到服务的弹性伸缩,就需要有一种机制来实现。这种机制就是服务注册和发现。当然,这不是必需的。如果您的服务实例很少且稳定,则无需使用服务注册和发现。
服务注册和发现
通过服务注册和发现,客户端不需要配置每个服务实例的地址core 注册机,而是从注册中心获取。注册中心如何保证每个地址的可用性,如果一个实例挂了怎么办?挂机的实例原则上不应该被客户端获取,所以需要提一下:健康检查。
常见的注册表是 , , etcd 。
官网:主要功能包括服务注册与发现、健康检查、KV存储、多数据中心等。
已成功运行。
服务注册
封装在这个类库中的api操作方便我们直接使用。当然,自己写http调用的接口也不是不可能。. . 接口说明:
。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"//注意,docker容器内部无法使用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();
}
}
复制
至此,服务注册、注销、健康检查等功能的代码编写已经完成。
运行服务
继续运行服务实例,如果不习惯可以用控制台启动。--:参数是传入容器的端口信息。
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 项服务:
可以看到停止的服务已经被删除了。请注意,当我们停止程序时,它会被主动调用以删除。
//应用程序终止时,取消注册
lifetime.ApplicationStopping.Register(() =>
{
consulClient.Agent.ServiceDeregister(registration.ID).Wait();
});
复制
当然,如果程序发生异常core 注册机,健康检查未能正确响应,也会被移除core 注册机,有一点区别。
至此,注册、发现、健康检查功能就完成了。下一步是考虑客户端如何获取这些服务实例的地址。
代码放置在:
未完待续...
发表评论