客户端实践
安装Consul
封装扩展
只贴部分核心代码,具体可以查看demo源码。
注入ConsulClient
public static IServiceCollection AddConsul(this IServiceCollection serviceCollection, Action<ConsulConfiguration> optionAction) { _consulConfiguration = new ConsulConfiguration(); optionAction(_consulConfiguration); var consulClient = new ConsulClient(x => x.Address = new Uri(_consulConfiguration.Host)); serviceCollection.AddSingleton(consulClient); return serviceCollection; } 把当前服务注册到Consul private static ConsulConfiguration _consulConfiguration; public static IApplicationBuilder UseConsul(this IApplicationBuilder app, IApplicationLifetime lifetime, Action<ServerConfiguration> optionAction) { var consulClient = app.ApplicationServices.GetService<ConsulClient>(); if (consulClient == null) throw new Exception("please AddConsul first"); var serverConfiguration = new ServerConfiguration(); optionAction(serverConfiguration); var serviceRegistration = GetServiceRegistration(serverConfiguration); //添加注册 consulClient.Agent.ServiceRegister(serviceRegistration).Wait(); //取消注册 lifetime.ApplicationStopping.Register(() => { consulClient.Agent.ServiceDeregister(serviceRegistration.ID).Wait(); }); return app; } private static Uri GetSelfUri(string uristring) { return new Uri(uristring); } private static AgentServiceRegistration GetServiceRegistration(ServerConfiguration serverConfiguration) { var localIp = GetSelfUri(serverConfiguration.SelfHost); var serviceRegistration = new AgentServiceRegistration { Check = new AgentServiceCheck//健康检查 { DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(60), Interval = TimeSpan.FromSeconds(30), HTTP = $"http://{localIp.Host}:{localIp.Port}/api/health", Timeout = TimeSpan.FromSeconds(3) }, ID = Guid.NewGuid().ToString("N"), Name = serverConfiguration.ServerName, Address = localIp.Host, Port = localIp.Port, Tags = new[] { serverConfiguration.ServerName } }; return serviceRegistration; }
添加健康检查接口
与上述封装可以在同一个库,避免每个web服务都要写一个
[Route("api/[Controller]")] public class HealthController : Controller { [HttpGet] public OkResult Get() { return Ok(); } }
在Startup.cs对Consul封装进行调用
ConfigureServices
public void ConfigureServices(IServiceCollection services) { services.AddOptions().AddConsul(option => { option.WithHost(Configuration["ConsulConfiguration:Host"]); }).AddMvc(); }
Configure
app.UseConsul(lifetime, option => { option.WithSelfHost(Configuration["SelfHost"]); option.WithServerName(Configuration["ConsulConfiguration:ServerName"]); });
K/V扩展
只实现了put、get、delete,剩下可以自行按需添加
public static class ConsulKyExtensions { public static async Task<bool> KvPutAsync(this ConsulClient consulClient, string key, string value) { var kvPair = new KVPair(key) { Value = Encoding.UTF8.GetBytes(value) }; var result = await consulClient.KV.Put(kvPair); if (result.StatusCode == HttpStatusCode.OK) return result.Response; return false; } public static bool KvPut(this ConsulClient consulClient, string key, string value) { var kvPair = new KVPair(key) { Value = Encoding.UTF8.GetBytes(value) }; var result = consulClient.KV.Put(kvPair).ConfigureAwait(false).GetAwaiter().GetResult(); if (result.StatusCode == HttpStatusCode.OK) return result.Response; return false; } public static async Task<string> KvGetAsync(this ConsulClient consulClient, string key) { var result = await consulClient.KV.Get(key); return Encoding.UTF8.GetString(result.Response.Value); } public static string KvGet(this ConsulClient consulClient, string key) { var result = consulClient.KV.Get(key).ConfigureAwait(false).GetAwaiter().GetResult(); return Encoding.UTF8.GetString(result.Response.Value); } public static async Task<bool> KvDeleteAsync(this ConsulClient consulClient, string key) { var result = await consulClient.KV.Delete(key); if (result.StatusCode == HttpStatusCode.OK) return result.Response; return false; } public static bool KvDelete(this ConsulClient consulClient, string key) { var result = consulClient.KV.Delete(key).ConfigureAwait(false).GetAwaiter().GetResult(); if (result.StatusCode == HttpStatusCode.OK) return result.Response; return false; } }
部署启动
修改appsettings.json,填写目标consul地址和本服务地址
{ "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Warning" } }, "ConsulConfiguration": { "Host": "http://192.168.20.80:8500", "ServerName": "ConsulWebDemo", "Id": "20E2CFBB-95C0-496A-B70F-11111111" }, "SelfHost": "http://localhost:1495/" }
启动后,如果服务正常则可以显示下图效果。