.NET Consul客户端封装演进
在ASP.NET Core中集成Consul服务发现时,直接使用原生客户端会导致代码重复。以下是基础实现示例:
服务注册配置
using Consul;
using Microsoft.Extensions.Options;
var appBuilder = WebApplication.CreateBuilder(args);
appBuilder.Services.AddControllers();
appBuilder.Services.AddSwaggerGen(config =>
{
config.SwaggerDoc("v1", new OpenApiInfo
{
Title = "Consul集成示例",
Version = "v1"
});
});
var app = appBuilder.Build();
app.Map("/health", context =>
{
app.Logger.LogInformation("Consul健康检查触发");
return context.Response.WriteAsync("OK");
});
RegisterConsulService(app);
app.Run();
async Task RegisterConsulService(WebApplication host)
{
using var consul = new ConsulClient(cfg =>
{
cfg.Address = new Uri(app.Configuration["Consul:Address"]);
cfg.Datacenter = app.Configuration["Consul:DataCenter"];
});
var reg = new AgentServiceRegistration
{
ID = Guid.NewGuid().ToString(),
Name = "webapi-service",
Address = "192.168.1.100",
Port = 8080,
Check = new AgentServiceCheck
{
HTTP = "http://192.168.1.100:8080/health",
Interval = TimeSpan.FromSeconds(5)
}
};
await consul.Agent.ServiceRegister(reg);
}
服务管理控制器
[ApiController]
[Route("api/[controller]")]
public class ServiceController : ControllerBase
{
private readonly IConfiguration _config;
private readonly ILogger<ServiceController> _logger;
public ServiceController(IConfiguration config, ILogger<ServiceController> logger)
{
_config = config;
_logger = logger;
}
[HttpGet("services")]
public async Task<IActionResult> GetAllServices()
{
using var consul = CreateClient();
var result = await consul.Health.Service("webapi-service");
return Ok(result.Response.Select(s => s.Service));
}
[HttpPost("register")]
public async Task<IActionResult> RegisterService(ServiceRegistration req)
{
using var consul = CreateClient();
var reg = new AgentServiceRegistration
{
ID = req.ServiceId,
Name = req.ServiceName,
Port = req.Port,
Check = new AgentServiceCheck
{
HTTP = req.HealthCheckUrl,
Interval = TimeSpan.FromSeconds(req.CheckInterval)
}
};
await consul.Agent.ServiceRegister(reg);
return Ok();
}
private ConsulClient CreateClient()
{
return new ConsulClient(cfg =>
{
cfg.Address = new Uri(_config["Consul:Address"]);
cfg.Datacenter = _config["Consul:DataCenter"];
});
}
}
配置文件示例
{
"Consul": {
"Address": "http://consul-server:8500",
"DataCenter": "dc1"
}
}
当前实现存在客户端重复创建和配置分散的问题,需要通过封装优化代码结构。