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