服务注册与发现Consul

下载 https://www.consul.io/

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、需要自己做负载均衡

posted @ 2020-03-30 21:43  永远的地平线  阅读(265)  评论(0)    收藏  举报