服务注册与发现Consul
windows 下就一个文件,直接运行
#开发模式,就不用配其他参数了
consul.exe agent -dev
#
consul.exe agent -server -data-dir=d:\consul\data\ -ui
c# 服务端
public static void RegisterConsul(this IConfiguration configuration)
{
var host = Evnironment.MachineName;
var port = int.Parse(configuration["port"]); //从配置中取端口参数
var client = new ConsulClient(c=>c.Address=new Uri("http://127.0.0.1:8500"));
var registration = new AgentServiceRegistration()
{
Check = new AgentServiceCheck(){
HTTP = $"http://{host}:{port}/Api/Health",
Interval = TimeSpan.FromSeconds(1),
DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(10),
Timeout = TimeSpan.FromSeconds(5)
},
Address = host,
Port = port,
ID = host+":"+port,
Name = "TestService",
};
client.Agent.ServiceRegister(registration);
}
运行服务 dotnet Service.dll --urls=http://*:7777 --port=7777
这里有两个地方要注意:
1、服务的ID一定要用唯一的,否则每次启动都注册一个服务,健康检查又能通过,后面就麻烦了
2、还是服务失效的问题,consul不会立即发现,需要客户端做容灾处理
客户端
protected string InvokeApi(string url)
{
var client = new ConsulClient(c=>c.Address=new Uri("http://127.0.0.1:8500"));
var result = client.Agent.Services().Result;
if (result.StatusCode != HttpStatusCode.OK)
throw new ApplicationException("Consul return:" + result.StatusCode);
var services = result.Response.Values.ToArray();
var nIndex = (new Random()).Next() % services.Length;
var server = services[nIndex];
using var httpClient = new HttpClient();
Console.WriteLine(url);
var resp = httpClient.GetAsync($"http://{server.Address}:{server.Port}{url}").Result;
if (!resp.IsSuccessStatusCode)
throw new ApplicationException("http request error:" + resp.StatusCode.ToString());
return resp.Content.ReadAsStringAsync().Result;
}
这里需要特别注意的就是
1、请求consul会有异常,请求回来的服务端也可能是已经失效了的
2、需要自己做负载均衡

浙公网安备 33010602011771号