Consul windows部署见上篇 Consul Windows部署 - 咸鱼翻身? - 博客园 (cnblogs.com)
一、创建Web API 项目并安装Consul包
打开命令行并运行以下命令创建一个新的 Web API 项目:
dotnet new webapi -n ConsulDemo
cd ConsulDemo
dotnet add package Consul
dotnet add package Microsoft.AspNetCore.HealthChecks.UI
二、配置 Consul 客户端
创建一个服务来注册Web API 到 Consul。可以在 Program.cs
中进行配置
Consul 客户端只能接受一个地址,因此需要实现一个逻辑,在连接失败时轮询下一个 Consul 服务器。这里是一个简单的策略,尝试多个 Consul 服务器地址:
(一) ConsulHelper.cs
using Consul;
public class ConsulHelper
{
private readonly string[] _consulServers;
public ConsulHelper(string[] consulServers)
{
_consulServers = consulServers;
}
// 连接到 Consul 并返回连接的 ConsulClient
public async Task<ConsulClient> ConnectConsulAsync()
{
foreach (var server in _consulServers)
{
try
{
var consulClient = new ConsulClient(config =>
{
config.Address = new Uri(server);
});
// 测试连接
var services = await consulClient.Agent.Services();
Console.WriteLine($"Connected to Consul at {server}");
return consulClient;
}
catch (HttpRequestException)
{
Console.WriteLine($"Failed to connect to Consul at {server}, trying next...");
}
}
throw new Exception("Failed to connect to any Consul servers.");
}
// 注册服务到 Consul
public async Task RegisterServiceAsync(ConsulClient consulClient, string serviceId, string serviceName, string address, int port, string[] tags = null)
{
var registration = new AgentServiceRegistration()
{
ID = serviceId,
Name = serviceName,
Address = address,
Port = port,
Tags = tags ?? new[] { "api", serviceName },
Check = new AgentServiceCheck
{
HTTP = $"http://{address}:{port}/health",
Interval = TimeSpan.FromSeconds(10),
Timeout = TimeSpan.FromSeconds(5)
}
};
await consulClient.Agent.ServiceRegister(registration);
Console.WriteLine($"Service {serviceName} registered with ID {serviceId}");
}
// 注销服务
public async Task DeregisterServiceAsync(ConsulClient consulClient, string serviceId)
{
await consulClient.Agent.ServiceDeregister(serviceId);
Console.WriteLine($"Service {serviceId} deregistered");
}
}
(二) Program.cs
using Microsoft.Extensions.Diagnostics.HealthChecks;
var builder = WebApplication.CreateBuilder(args);
// 添加必要的服务
builder.Services.AddControllers();
// 添加健康检查服务
builder.Services.AddHealthChecks()
.AddCheck("self", () => HealthCheckResult.Healthy("The service is healthy"));
// 创建应用
var app = builder.Build();
// Consul 服务器集群地址
var consulServers = new[]
{
"http://consul-server-1:8500",
"http://consul-server-2:8500",
"http://consul-server-3:8500"
};
// 创建 ConsulHelper 实例
var consulHelper = new ConsulHelper(consulServers);
// 连接到 Consul 并注册服务
var serviceId = $"my-api-20240911";
var consulClient = await consulHelper.ConnectConsulAsync();
await consulHelper.RegisterServiceAsync(consulClient, serviceId, "my-api-service", "<本机ip>", 5048);
// 在应用关闭时注销服务
app.Lifetime.ApplicationStopping.Register(async () =>
{
await consulHelper.DeregisterServiceAsync(consulClient, serviceId);
});
// 配置 HTTP 请求管道
app.MapControllers();
app.MapHealthChecks("/health");
// 启动应用
app.Run();
运行项目并查看Consul ui
三、客户端调用
(一) 创建控制台项目
使用 .NET CLI 创建控制台项目:
dotnet new console -n ConsulServiceDiscoveryConsole
cd ConsulServiceDiscoveryConsole
dotnet add package Consul
(二) 创建 ConsulServiceDiscovery 类
在控制台项目中创建一个 ConsulServiceDiscovery
类,用来从 Consul 获取已注册的服务。
ConsulServiceDiscovery.cs
using Consul;
using System;
using System.Linq;
using System.Threading.Tasks;
public class ConsulServiceDiscovery
{
private readonly ConsulClient _consulClient;
public ConsulServiceDiscovery(string consulAddress)
{
// 初始化 Consul 客户端
_consulClient = new ConsulClient(config =>
{
config.Address = new Uri(consulAddress);
});
}
// 获取服务实例的地址
public async Task<Uri> GetServiceUriAsync(string serviceName, string tag = null)
{
// 查询 Consul 中的服务
var queryResult = await _consulClient.Health.Service(serviceName, tag, passingOnly: true);
// 选择一个健康的服务实例
var service = queryResult.Response.FirstOrDefault();
if (service == null)
{
throw new Exception($"Service {serviceName} not found in Consul.");
}
var address = service.Service.Address;
var port = service.Service.Port;
// 返回服务的 URI
return new Uri($"http://{address}:{port}");
}
}
(三) 更新 Program.cs
在 Program.cs
中使用 ConsulServiceDiscovery
来从 Consul 获取服务信息,并调用 Web API。
Program.cs
class Program
{
static async Task Main(string[] args)
{
// Consul 服务器地址
string consulAddress = "http://<consul地址>"; // 这里直接取其中一个,如需负载,可轮询或其他方式
// 创建 ConsulServiceDiscovery 实例
var serviceDiscovery = new ConsulServiceDiscovery(consulAddress);
// 目标服务名称(注册到 Consul 中的服务名称)
string serviceName = "my-api-service"; // 你注册到 Consul 的 Web API 服务名称
try
{
// 获取 Web API 服务的地址
var serviceUri = await serviceDiscovery.GetServiceUriAsync(serviceName);
Console.WriteLine($"Discovered service at: {serviceUri}");
// 使用 HttpClient 进行调用
var httpClient = new HttpClient();
string url = $"{serviceUri}health";
var result = await httpClient.GetStringAsync(url);
Console.WriteLine($"Service response: {result}");
Console.ReadKey();
}
catch (Exception ex)
{
Console.WriteLine($"Service discovery failed: {ex.Message}");
}
}
}
返回Healthy 调用成功。
标签:string,Consul,consulClient,serviceId,使用,var,new,Net From: https://www.cnblogs.com/mchao/p/18408638