consul
Consul 是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其它分布式服务注册与发现的方案相比,Consul的方案更“一站式”,内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其它工具(比如ZooKeeper等) ,使用起来也较为简单。
Consul 使用Go语言编写,因此具有天然可移植性(支持Linux,Windows和Mac OS);安装包仅包含一个可执行文件,方便部署,与Docker等轻量级容器可无缝配合。
Consul 官网:https://www.consul.io/
Consul 官网介绍:https://www.consul.io/docs
Consul 中文教程:https://www.springcloud.cc/spring-cloud-consul.html
总结就是,当服务多了比较麻烦,就用服务发现的方式处理。
网上很多consul的介绍,可以自己了解。
注册
启动consul,用开发模式。输入命令:consul agent --dev -node=ip
webapi服务注册,大家可以在网上搜索,我直接贴代码聊。
nuget引入Consul。
加入注册代码。
public static class ConsulManager
{
public static void UssConsul(this IApplicationBuilder app, IHostApplicationLifetime lifetime, IConfiguration configuration, IConsulClient consulClient)
{
RegServer(configuration,lifetime, consulClient);
}
/// <summary>
/// 注册微服务
/// </summary>
/// <param name="configuration"></param>
/// <param name="consul"></param>
private static void RegServer(IConfiguration configuration, IHostApplicationLifetime lifetime, IConsulClient consul)
{
string consulService = configuration["Service:Name"];//获取appsettings.json文件里的ConsulGroup节点数据;
string urlPath =configuration["UrlPath"];//获取appsettings.json文件里的UrlPath节点数据;
string ip = string.IsNullOrWhiteSpace(configuration["Service:ip"]) ? "127.0.0.1" : configuration["Service:ip"];//ip值是在启动服务时传入的参数
int port = Convert.ToInt32(configuration["Service:port"]) == 0 ? 80 : Convert.ToInt32(configuration["Service:port"]);//port值是在启动服务时传入的参数
string serviceId = $"{consulService}_{ip}_{port}_{Guid.NewGuid()}";
string chkInterval = string.IsNullOrWhiteSpace(configuration["Service:Check:Interval"])? "2" : configuration["Service:Check:Interval"];
string chkAddress = string.IsNullOrWhiteSpace(configuration["Service:Check:Address"]) ? "http://{ip}:{port}/api/Health" : configuration["Service:Check:Address"];
string chkTimeOut= string.IsNullOrWhiteSpace(configuration["Service:Check:Interval"]) ? "10" : configuration["Service:Check:Interval"];
string chkDeregisterCriticalServiceAfter= string.IsNullOrWhiteSpace(configuration["Service:Check:DeregisterCriticalServiceAfter"]) ? "10" : configuration["Service:Check:DeregisterCriticalServiceAfter"];
//设置心跳包
var httpCheck = new AgentServiceCheck()
{
// Interval = TimeSpan.FromSeconds(10),//间隔多久心跳检测一次
// HTTP = $"http://{ip}:{port}/{urlPath}",//心跳检查地址,本服务提供的地址
HTTP = $"http://localhost:7002/api/Health",//心跳检查地址,本服务提供的地址
// Timeout = TimeSpan.FromSeconds(2),//心跳检测超时时间
// DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(10),//心跳检测失败多久后注销
// Method= "GET",
Interval = TimeSpan.FromSeconds(Convert.ToInt32(chkInterval)),
// HTTP=chkAddress,
Timeout = TimeSpan.FromSeconds(Convert.ToInt32(chkTimeOut)),
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(Convert.ToInt32(chkDeregisterCriticalServiceAfter)),
Method = "GET",
};
//配置微服务信息
var regist = new AgentServiceRegistration
{
Checks = new[] { httpCheck }, //心跳检测设置
Address = ip,
Port = port,
Name = consulService,
ID = serviceId,
Tags = new[] { $"urlprefix-/{consulService}" }
};
lifetime.ApplicationStopping.Register(() =>
{
consul.Agent.ServiceDeregister(regist.ID).Wait();//服务停止时取消注册
});
consul.Agent.ServiceRegister(regist);//注册微服务!
}
}
配置文件加入
"Service": {
"Name": "homepage",
"IP": "localhost",
"Port": "7002",
"Check": {
"Interval": "10",
"Address": "http://192.168.0.106:7002/api/Health",
"Timeout": "2",
"DeregisterCriticalServiceAfter": "10",
}
},
"Consul": {
"IP": "localhost",//consul地址
"Port": "8500"//consul端口
}
程序中加入代码
string ip = builder.Configuration["Consul:IP"];
int port = Convert.ToInt32(builder.Configuration["Consul:Port"]);
string consuladdr = $"http://{ip}:{port}";
builder.Services.AddSingleton<IConsulClient>(new ConsulClient(tt =>
{
tt.Address = new Uri(consuladdr);
tt.Datacenter = "dc1";
}));
//..........
app.UssConsul(app.Lifetime, app.Configuration, app.Services.GetService<IConsulClient>());
增加健康检查接口
[Route("api/[controller]")]
[ApiController]
public class HealthController : ControllerBase
{
#region 依赖注入
private readonly ILogger<HealthController> _logger;
private IConfiguration _IConfiguration;
public HealthController(ILogger<HealthController> logger, IConfiguration configuration)
{
_logger = logger;
_IConfiguration = configuration;
}
#endregion
[HttpGet]
public IActionResult Check()
{
this._logger.LogInformation($"{this._IConfiguration["port"]}- Health Check!");
return Ok("ok");//200
}
}
WebAPi服务实现向consul注册。
ocelot使用consul获取服务
项目中nuget引入 Ocelot 、Ocelot.Provider.consul
配置中间件
builder.Services.AddOcelot(builder.Configuration).AddConsul().AddPolly(); //加 Consul服务 polly
配置ocelot.json
WebAPi中注册一个values控制器。访问:https://localhost:5000/ss/Values
可以先在consul中查看注册服务。
这里我没有什么讲解,因为网上很多,我还是推荐几篇文章
.NET 5 微服务之 Ocelot + Consul_**Dragon**的博客-CSDN博客_consul加ocelot
.NET Core 微服务 - API 网关之 Ocelot 与 Consul 服务发现 - ITPOW (cftea.com)