记一次使用Consul进行服务注册和服务发现
服务注册与发现
因为Consul对.net core的支撑和对Ocelot的高度兼容性,所以,.net core使用的服务注册与发现的组件大多数使用的Consul。
首先。我有一个测试服务A。这个服务会进行服务注册。用于对外提供服务。
服务A :
首先,Nuget安装Consul
添加一个扩展类ConsulExtensions
public static class ConsulExtensions { public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IConfiguration configuration)//, IHostApplicationLifetime lifetime) { var consulClient = new ConsulClient(c => { c.Address = new Uri(configuration["ConsulSetting:ConsulAddress"]); }); var registration = new AgentServiceRegistration() { ID = Guid.NewGuid().ToString(),//服务实例唯一标识 Name = configuration["ConsulSetting:ServiceName"],//服务名 Address = configuration["ConsulSetting:ServiceIP"], //服务IP Port = int.Parse(configuration["ConsulSetting:ServicePort"]),//服务端口 因为要运行多个实例,端口不能在appsettings.json里配置,在docker容器运行时传入 Check = new AgentServiceCheck() { DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务启动多久后注册 Interval = TimeSpan.FromSeconds(10),//健康检查时间间隔 HTTP = $"http://{configuration["ConsulSetting:ServiceIP"]}:{configuration["ConsulSetting:ServicePort"]}{configuration["ConsulSetting:ServiceHealthCheck"]}",//健康检查地址 Timeout = TimeSpan.FromSeconds(5)//超时时间 } }; //服务注册 consulClient.Agent.ServiceRegister(registration).Wait(); ////应用程序终止时,手动取消注册 //lifetime.ApplicationStopping.Register(() => //{ // consulClient.Agent.ServiceDeregister(registration.ID).Wait(); //}); return app; } }
在Starup里面注册Consul服务
app.RegisterConsul(context.GetConfiguration());
在appsettings.json里面添加配置
"ConsulSetting": { "ServiceName": "TestService", "ServiceIP": "localhost", "ServiceHealthCheck": "/healthcheck", "ServicePort": "5000", "ConsulAddress": "http://localhost:8500" }
启动服务,在Consul里面就能看见这个服务已经注册进去了
现在再开始进入测试服务B,这个服务用于服务发现,并调用测试服务A的接口。
首先,还是先安装Consul组件。然后创建一个IConsulTestAppService,并用ConsulTestAppService实现它。
public class ConsulTestAppService : IConsulTestAppService { private readonly IConfiguration _configuration; public ConsulTestAppService(IConfiguration configuration) { _configuration = configuration; } public async Task<string> GetAsync() { var consulClient = new ConsulClient(c => { //consul地址 c.Address = new Uri(_configuration["ConsulSetting:ConsulAddress"]); }); var services = consulClient.Health.Service("TestService", null, true, null).Result.Response;//健康的服务 string[] serviceUrls = services.Select(p => $"http://{p.Service.Address + ":" + p.Service.Port}").ToArray();//订单服务地址列表 if (!serviceUrls.Any()) { return await Task.FromResult("【TestService】服务列表为空"); } //每次随机访问一个服务实例 var Client = new RestClient(serviceUrls[new Random().Next(0, serviceUrls.Length)]); var request = new RestRequest("/api/test/GetOne", Method.GET); var response = await Client.ExecuteAsync(request); return response.Content; } }
我这里使用RestSharp来进行Http请求。
访问服务,TestService已经正常响应数据。