Consul 学习笔记-服务注册

Consul简介:

  Consul是一种服务网格解决方案,提供具有服务发现,配置和分段功能的全功能控制平面。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建完整的服务网格。Consul需要一个数据平面,并支持代理和本机集成模型。Consul附带了一个简单的内置代理,因此开箱即用,但也支持Envoy等第三方代理集成。

 特点:

  • 服务发现: Consul的客户端可用提供一个服务,比如 api 或者mysql ,另外一些客户端可用使用Consul去发现一个指定服务的提供者.通过DNS或者HTTP应用程序可用很容易的找到他所依赖的服务.
  • 健康检查: Consul客户端可用提供任意数量的健康检查,指定一个服务(比如:webserver是否返回了200 OK 状态码)或者使用本地节点(比如:内存使用是否大于90%). 这个信息可由operator用来监视集群的健康.被服务发现组件用来避免将流量发送到不健康的主机.
  • Key/Value存储: 应用程序可用根据自己的需要使用Consul的层级的Key/Value存储.比如动态配置,功能标记,协调,领袖选举等等,简单的HTTP API让他更易于使用.
  • 多数据中心: Consul支持开箱即用的多数据中心.这意味着用户不需要担心需要建立额外的抽象层让业务扩展到多个区域.

Consul安装运行:

 Consul支持各种平台的安装,可以前往//www.consul.io/downloads.html下载相关安装包,也可以使用docker部署,本次采用docker部署方式实现:

 1、拉取consul镜像  

docker pull consul

 2、配置并运行Consul服务器  

docker run \
    -d \
    -p 8500:8500 \
    -p 8600:8600/udp \
    --name=badger \
    consul agent -server -ui -node=server -bootstrap-expect=1 -client=0.0.0.0

 3、打开地址//localhost:8500/ui/dc1/services查看consului界面,基本运行效果如下图:

  

简单使用

 添加Consul服务集群:使用 Docker 搭建 3个 server 节点 + 1 个 client 节点,API 服务通过 client 节点进行服务注册和发现  

version: "3"

services:
  service_1:
    image: consul
    command: agent -server -client=0.0.0.0 -bootstrap-expect=3 -node=service_1
    volumes:
      - /usr/local/docker/consul/data/service_1:/data
  service_2:
    image: consul
    command: agent -server -client=0.0.0.0 -retry-join=service_1 -node=service_2
    volumes:
      - /usr/local/docker/consul/data/service_2:/data
    depends_on:
      - service_1
  service_3:
    image: consul
    command: agent -server -client=0.0.0.0 -retry-join=service_1 -node=service_3
    volumes:
      - /usr/local/docker/consul/data/service_3:/data
    depends_on:
      - service_1
  client_1:
    image: consul
    command: agent -client=0.0.0.0 -retry-join=service_1 -ui -node=client_1
    ports:
      - 8500:8500
    volumes:
      - /usr/local/docker/consul/data/client_1:/data
    depends_on:
      - service_2

 添加:docker-compose.yaml文件,执行docker-compose up命令

 本次继续使用 IdentityServer.Demo 中,cz.Api.Goods、cz.Api.Order两个项目进行改造,实现服务注册和服务发现效果,首先调整两个接口方法返回结果:

cz.Api.Goods项目:
public IActionResult Get()
{
    var result = new
    {
        Message = $"Name:{nameof(cz.Api.Goods)},Time:{DateTime.Now}",
        LocalIp = Request.HttpContext.Connection.LocalIpAddress.ToString(),
    };
    return Ok(result);
}

cz.Api.Order项目:
[HttpGet]
public IActionResult Get()
{
    var result = new
    {
        Message = $"Name:{nameof(cz.Api.Order)},Time:{DateTime.Now}",
        IP = Request.HttpContext.Connection.LocalIpAddress.ToString(),
    };
    return Ok(result);
}

  

  • 服务注册:

    1、添加Consul配置内容:

 "Consul": {
    "Address": "//host.docker.internal:8500",
    "HealthCheck": "/healthcheck",
    "Name": "cz.Api.Goods",
    "Ip": "host.docker.internal"
  }

     因为会在docker中运行:使用host.docker.internal代替localhost

    2、注册Consul组件:

     A:在两个项目中添加Consul包:使用命令:Install-Package Consul、

     B:添加心跳检查控制器:      

[Route("api/[controller]")]
[ApiController]
public class HealthCheckController : ControllerBase
{
    /// <summary>
    /// 健康检查
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public IActionResult api()
    {
        return Ok();
    }
}

 

     C:注册组件:在项目项目中添加ConsulExtensions方法类:

public static class ConsulExtensions
{
    public static IApplicationBuilder UseConul(this IApplicationBuilder app, IConfiguration configuration, IHostApplicationLifetime lifetime)
    {
        var client = new ConsulClient(options =>
        {
            // Consul客户端地址
            options.Address = new Uri(configuration["Consul:Address"]);
        });

        var registration = new AgentServiceRegistration
        {
            // 唯一Id
            ID = Guid.NewGuid().ToString(),
            // 服务名
            Name = configuration["Consul:Name"],
            // 服务绑定IP
            Address = configuration["Consul:Ip"],
            // 服务绑定端口
            Port = Convert.ToInt32(configuration["Consul:Port"]),
            Check = new AgentServiceCheck
            {
                // 服务启动多久后注册
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                // 健康检查时间间隔
                Interval = TimeSpan.FromSeconds(10),
                // 健康检查地址
                HTTP = $"//{configuration["Consul:Ip"]}:{configuration["Consul:Port"]}{configuration["Consul:HealthCheck"]}",
                // 超时时间
                Timeout = TimeSpan.FromSeconds(5)
            }
        };

        // 注册服务
        client.Agent.ServiceRegister(registration).Wait();
        // 应用程序终止时,取消服务注册
        lifetime.ApplicationStopping.Register(() =>
        {
            client.Agent.ServiceDeregister(registration.ID).Wait();
        });

        return app;
    }
}

 

      在Startup文件中:使用该方法:      

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime)
{
   ……
   app.UseConul(Configuration, lifetime);
}

 

    D:添加Docker操作,编译镜像;运行镜像

      在解决方案所在目录执行docker命令:      

编译镜像:
docker build -t cz.api.goods:dev -f ./cz.Api.Goods/Dockerfile . docker build -t cz.api.order:dev -f ./cz.Api.Order/Dockerfile .
运行镜像

 docker run -d -p 5050:80 –name cz.api.goods_1 cz.api.goods:dev
 docker run -d -p 5051:80 –name cz.api.goods_2 cz.api.goods:dev
 docker run -d -p 5052:80 –name cz.api.goods_3 cz.api.goods:dev

 docker run -d -p 5060:80 –name cz.api.order_1 cz.api.order:dev
 docker run -d -p 5061:80 –name cz.api.order_2 cz.api.order:dev
 docker run -d -p 5062:80 –name cz.api.order_3 cz.api.order:dev

 

        

    E:进入Consul的UI界面查看服务注册情况,注册成功

    

    

 

     

后续:

  后续将进一步对Consul进行学习验证,以及对原理进一步了解。

参考:

官方文档:

//www.consul.io/docs

//www.consul.io/docs/guides/containers-guide 

源码github: //github.com/cwsheng/Consul.Demo.git