core 注册机 .Net Core微服务入口全记录(二)——Consul-Service注册与发现(上)

Core微服务入门全纪录(一)——项目搭建】讲到要做到服务的灵活伸缩,那么需要有一种机制来实现它,这个机制就是服务注册与发现。有了服务注册与发现,客户端就不用再去配置各个服务实例的地址,改为从注册中心统一获取。的主要功能有服务注册与发现、健康检查、K-V存储、多数据中心等。至此就完成了服务注册,取消注册,健康检查等功能的代码编写。至此,6个服务器实例都已运行,并且成功注册到。...

前言

在上一篇文章【.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(() =>

core 注册机

{ 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 注册机,有一点区别。

至此,注册、发现、健康检查功能就完成了。下一步是考虑客户端如何获取这些服务实例的地址。

代码放置在:

未完待续...

相关文章

发表评论