以下为单机环境构建脚本,用于本机测试,生产环境中应当进行集群搭建
version: '3' services: consul: image: consul:1.7.1 container_name: consul volumes: - /c/docker/consul/data:/consul/data - /c/docker/consul:/consul/config ports: - 8300:8300 - 8301:8301 - 8301:8301/udp - 8302:8302 - 8302:8302/udp - 8400:8400 - 8500:8500 - 53:53/udp command: agent -server -bind=0.0.0.0 -client=0.0.0.0 -node=consul_Server1 -bootstrap-expect=1 -ui
成功搭建后,访问8500端口,你可以看到如下界面
点击 下载Consul
执行以下命令运行consul
consul agent -dev
配置前一篇文章中的ServiceA
Install-Package Consul -Version 0.7.2.6
public class ServiceDisvoveryOptions { public string ServiceName { get; set; } public ConsulOptions Consul { get; set; } } public class ConsulOptions { public string HttpEndpoint { get; set; } public DnsEndpoint DnsEndpoint { get; set; } } public class DnsEndpoint { public string Address { get; set; } public int Port { get; set; } public IPEndPoint ToIPEndPoint() { return new IPEndPoint(IPAddress.Parse(Address), Port); } }
"ServiceDiscovery": { "ServiceName": "ServiceA", "Consul": { "HttpEndpoint": "http://127.0.0.1:8500", "DnsEndpoint": { "Address": "127.0.0.1", "Port": 8600 } } }
private void ConfigureConsul(IApplicationBuilder app, IOptions<ServiceDisvoveryOptions> serviceOptions, IConsulClient consul, IHostApplicationLifetime lifetime) { var features = app.Properties["server.Features"] as FeatureCollection; var addresses = features.Get<IServerAddressesFeature>() .Addresses .Select(p => new Uri(p)); foreach (var address in addresses) { var serviceId = $"{serviceOptions.Value.ServiceName}_{address.Host}:{address.Port}"; var httpCheck = new AgentServiceCheck() { DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(1), Interval = TimeSpan.FromSeconds(30), HTTP = new Uri(address, "health").OriginalString }; var registration = new AgentServiceRegistration() { Checks = new[] { httpCheck }, Address = address.Host, ID = serviceId, Name = serviceOptions.Value.ServiceName, Port = address.Port }; consul.Agent.ServiceRegister(registration).GetAwaiter().GetResult(); lifetime.ApplicationStopping.Register(() => { consul.Agent.ServiceDeregister(serviceId).GetAwaiter().GetResult(); }); } }
public void ConfigureServices(IServiceCollection services) { services.AddOptions(); services.Configure<ServiceDisvoveryOptions>(Configuration.GetSection("ServiceDiscovery")); services.AddSingleton<IConsulClient>(p => new ConsulClient(cfg => { var serviceConfiguration = p.GetRequiredService<IOptions<ServiceDisvoveryOptions>>().Value; if (!string.IsNullOrEmpty(serviceConfiguration.Consul.HttpEndpoint)) { // if not configured, the client will use the default value "127.0.0.1:8500" cfg.Address = new Uri(serviceConfiguration.Consul.HttpEndpoint); } })); services.AddHealthChecks(); services.AddControllers(); }
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IOptions<ServiceDisvoveryOptions> serviceDisvoveryOptions, IConsulClient consul, IHostApplicationLifetime lifetime) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthorization(); ConfigureConsul(app, serviceDisvoveryOptions, consul, lifetime); app.UseHealthChecks("/health"); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
运行ServiceA
可以看到健康检查已通过,并且服务ServiceA已成功注册到Consul
安装nuget包依赖
Install-Package Ocelot.Provider.Consul -Version 14.0.11
在上一篇文章的基础上,我们先修改 ocelot.json
删除了ServiceA路由中的DownstreamHostAndPorts写死的地址和端口 ,改为使用 Consul 服务发现
{ "ReRoutes": [ { "DownstreamPathTemplate": "/{url}", "DownstreamScheme": "http", "UpstreamPathTemplate": "/service-a/{url}", "UpstreamHttpMethod": [ "Get", "Post" ], "AuthenticationOptions": { "AuthenticationProviderKey": "SampleKey", "AllowedScopes": [ "gateway_api" ] }, "ServiceName": "ServiceA", "LoadBalancerOptions": { "Type": "LeastConnection" } } ], "GlobalConfiguration": { "BaseUrl": "http://localhost", "ServiceDiscoveryProvider": { "Host": "localhost", "Port": 8500, "Type": "Consul" } } }
向容器中添加Consul服务
public void ConfigureServices(IServiceCollection services) { services.AddOcelot() .AddConsul(); }
启动各个服务,查看结果
可以看到已成功执行
Consul
Service Discovery And Health Checks In ASP.NET Core With Consul