06_NET中使用Consul(服務發現)

官網:Consul by HashiCorp 

中文文檔:Consul 中文文檔 | Consul 中文文檔 (gitbook.io)

安裝Consul

window安裝:Install | Consul | HashiCorp Developer

1. 選擇windows x64 版本(64bit)
2. 進入下載好的文件夾中,打開powershell ,執行命令,啓動服務端代理

consul.exe agent -dev

3. 瀏覽器輸入:http://IP:8500/出現ConsulWeb界面就表示成功了

-dev 表示開發模式,生產環境下不建議使用,因爲它不會保存任何狀態
-server 生產環境下可使用

 

Docker 安裝:

docker pull consul # 默認拉取latest
docker pull consul:1.15.4 # 拉取指定版本

安裝並運行

docker run -d -p 8500:8500 --restart=always --name=consul consul agent -server - bootstrap -ui -node=1 -client='0.0.0.0'

agent: 表示啓動 Agent 進程。
server:表示啓動 Consul Server 模式
client:表示啓動 Consul Cilent 模式。
bootstrap:表示這個節點是 Server-Leader ,每個數據中心只能運行一臺服務器。技術角度上講Leader 是通過 Raft 算法選舉的,但是集羣第一次啓動時需要一個引導 Leader,在引導羣集後,建議不要使用此標誌。
ui:表示啓動 Web UI 管理器,默認開放端口 8500,所以上面使用 Docker 命令把 8500 端口對外開放。
node:節點的名稱,集羣中必須是唯一的,默認是該節點的主機名。
client:consul服務偵聽地址,這個地址提供HTTP、DNS、RPC等服務,默認是127.0.0.1所以不對外提供服務,如果你要對外提供服務改成0.0.0.0
join:表示加入到某一個集羣中去。 如:-json=192.168.0.11。

 

使用Consul:

安裝包:Consul.AspNetCore

服務端

新建一個WebApi項目:Consul.ServiceA

修改appsettings.json配置文件

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Consul": {
    "HostAddress": "http://localhost:8500", 
    "ServiceAddress": "localhost",
    "Port": 5011,
    "ServerName": "Consul.ServiceA"
  }
}

HostAddress:Consul地址;   ServiceAddress:服務地址; Port:端口;  ServerName:服務名稱

添加映射類

public class ConsulOption
{
    public string HostAddress { get; set; }
    public string ServiceAddress { get; set; }
    public int Port { get; set; }
    public string ServerName { get; set; }
}

 

添加擴展類

public static class ConsulServiceExtension
{
    public static IServiceCollection AddConsulService(this IServiceCollection services, IConfiguration configuration )
    {
        //獲取配置文件信息
        var consulSection = configuration.GetSection("Consul");
        services.Configure<ConsulOption>(consulSection);
        var consulOption = consulSection.Get<ConsulOption>();

        //添加consul地址
        services.AddConsul(p =>
        {
            p.Address = new Uri(consulOption.HostAddress);
        });

        //註冊consul
        services.AddConsulServiceRegistration(p =>
        {
            p.ID = Guid.NewGuid().ToString();
            p.Name = consulOption.ServerName;
            p.Address = consulOption.ServiceAddress;
            p.Port = consulOption.Port;
            
            // 健康檢查
            p.Check = new()
            {
                // 1. 如果服務不可用(健康檢查失敗)的情況下,多久將當前服務移除
                DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),
                // 2. 健康檢查間隔時間
                Interval = TimeSpan.FromSeconds(10),
                // 3. 健康檢查地址(心跳地址)
                HTTP = $"http://{p.Address}:{p.Port}/health"
                // 4. 超時時間
                ,Timeout = TimeSpan.FromSeconds(5)
            };
        });

        return services;
    }
}

Program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddSwaggerGen();
builder.Services.AddConsulService(builder.Configuration);
var app = builder.Build();

app.UseSwagger();
app.UseSwaggerUI();

app.UseAuthorization();

app.MapControllers();

app.Run();

 

添加HealthController控制器

[ApiController]
[Route("[controller]")]
public class HealthController:ControllerBase
{

    [HttpGet]
    public IActionResult Check()
    {
        return Ok($"進行心跳檢測:{DateTime.Now}");
    }
    
}

 

客戶端:

新建一個webApi項目:Consul.Client

配置和服務端一致;appsettings.json的配置要記得修改;

 

-----------------------------------------------------漂亮的分割線-------------------------------------------------------------------------

測試:

服務端Consul.ServiceA添加一個控制器用於測試

[Route("[controller]/[action]")]
[ApiController]
public class ProductController:ControllerBase
{
    [HttpGet]
    public IActionResult GetProduct()
    {
        List<ProductInfo> list = new()
        {
            new() {Id = 1, Name = "商品1"},
            new() {Id = 2, Name = "商品2"}
        };
        return Ok(list);
    }
}

 

客戶端Consul.Client添加一個控制器ClientController 去調用服務端

[Route("[controller]/[action]")]
[ApiController]
public class ClientController:ControllerBase
{
    private readonly IConsulClient _consulClient;

    public ClientController(IConsulClient consulClient)
    {
        _consulClient = consulClient;
    }

    [HttpGet]
    public async Task<IActionResult> GetProductByClient()
    {
        var instanceList = (await _consulClient.Catalog.
            Service("Consul.ServiceA")).Response;
        //隨機獲取一個服務
        var instance = instanceList[new Random().Next(instanceList.Length)];

        using HttpClient client = new();
        var json = await client.GetStringAsync($"http://{instance.ServiceAddress}:{instance.ServicePort}/Product/GetProduct");
        var result = JsonConvert.DeserializeObject<List<ProductInfo>>(json);

        return Ok(result);
    }
}

 

-----------------------------------------------------漂亮的分割線-------------------------------------------------------------------------

添加多個服務端(集羣)

配置和Consul.ServiceA也是一樣的,appsettings.json的配置要記得修改

"Consul": {
    "HostAddress": "Consul地址", 
    "ServiceAddress": "服務端地址",
    "Port": 服務端口,
    "ServerName": "這裏的名稱都要一樣"
  }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章