.NET 5.0实现Consul服务注册
Consul是什么:(来自官方翻译)
Consul 是一种服务网格解决方案,提供具有服务发现、配置和分段功能的全功能控制平面。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建完整的服务网格。Consul 需要一个数据平面并支持代理和本地集成模型。Consul 附带一个简单的内置代理,因此一切都可以开箱即用,而且还支持 3rd 方代理集成,例如 Envoy。
Consul 的主要特点:(来自官方翻译)
-
服务发现:Consul 的客户端可以注册一个服务,例如
api
或mysql
,其他客户端可以使用 Consul 来发现给定服务的提供者。使用 DNS 或 HTTP,应用程序可以轻松找到它们所依赖的服务。 -
健康检查:Consul 客户端可以提供任意数量的健康检查,要么与给定的服务相关联(“网络服务器是否返回 200 OK”),要么与本地节点(“内存利用率是否低于 90%”)相关联。操作员可以使用此信息来监控集群健康状况,并且服务发现组件可以使用它来将流量路由到不健康的主机之外。
-
KV 存储:应用程序可以将 Consul 的分层键/值存储用于多种目的,包括动态配置、功能标记、协调、领导选举等。简单的 HTTP API 使其易于使用。
-
安全服务通信:Consul 可以为服务生成和分发 TLS 证书,以建立相互的 TLS 连接。 意图可用于定义允许哪些服务进行通信。可以通过实时更改意图轻松管理服务分段,而不是使用复杂的网络拓扑和静态防火墙规则。
-
多数据中心:Consul 支持开箱即用的多个数据中心。这意味着 Consul 的用户不必担心构建额外的抽象层以扩展到多个区域。
Consul 旨在对 DevOps 社区和应用程序开发人员友好,使其非常适合现代、弹性的基础设施。
操作系统Linux CentOS8.2、.NET 5.0、
一.安装Consul
进入/usr/local/src目录
cd /usr/local/src
下载consul安装压缩包
wget http://releases.hashicorp.com/consul/1.10.1/consul_1.10.1_linux_amd64.zip
解压压缩包到当前目录
unzip consul_1.10.1_linux_amd64.zip
解压后有一个名字为consul的可执行文件
查看版本号
./consul --version
版本号为v1.10.1
创建consul.server目录,并把consul文件移动到coonsul.server目录
mkdir consul.server
mv consul consul.server
在consul.server目录里创建consul.d目录
cd consul.server
mkdir consul.d
在consul.d目录中创建webservice.json文件
cd consul.d/
touch webservice.json
./consul agent -server -ui -bootstrap-expect=1 -data-dir=/usr/local/src/consul.server -node=agent-one -advertise=172.19.43.49 -bind=0.0.0.0 -client=0.0.0.0
访问8500端口即可看到consul注册节点
二.注册服务
创建一个.NET Core工程,添加Consul包。
添加一个名为HealthController的控制器,并实现一个get请求的接口用于服务健康检查,接口返回StatusCode为200。
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Pudefu.Web.Controllers { [Route("api/[controller]")] [ApiController] public class HealthController : ControllerBase { [HttpGet] public JsonResult Get() { return new JsonResult("OK"); } } }
在配置文件appsettings.json添加配置
"ConsulConfig": { "ServiceId": "d72e7de8b01a43acac640b1a00b26c81", "ServiceName": "pudefu.web", "ServiceIP": "xxx.xx.xxx.xx",//当前应用部署的服务器IP地址 "ServicePort": 8000,//当前应用部署的服务器端口 "ConsulIP": "xxx.xx.xxx.xx",//Consul部署的服务器IP地址 "ConsulPort": 8500//Consul端口 }
添加服务配置模型
public class ServiceConfig { /// <summary> /// 服务唯一ID /// </summary> public string ServiceId { get; set; } /// <summary> /// 服务部署的IP /// </summary> public string ServiceIP { get; set; } /// <summary> /// 服务部署的端口 /// </summary> public int ServicePort { get; set; } /// <summary> /// 服务名称 /// </summary> public string ServiceName { get; set; } /// <summary> /// consul部署的IP /// </summary> public string ConsulIP { get; set; } /// <summary> /// consul端口 /// </summary> public int ConsulPort { get; set; } }
添加Consul注册类
public static class AppBuilderExtensions { public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IHostApplicationLifetime lifetime, ServiceConfig serviceConfig) { var consulClient = new ConsulClient(x => x.Address = new Uri($"http://{serviceConfig.ConsulIP}:{serviceConfig.ConsulPort}")); var httpCheck = new AgentServiceCheck() { DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务器启动5秒后注册 Interval = TimeSpan.FromMinutes(1),//每分钟检测一次(健康检查间隔时间) HTTP = $"http://{serviceConfig.ServiceIP}:{serviceConfig.ServicePort}/api/health",//本服务健康检查地址 Timeout = TimeSpan.FromSeconds(20), }; var registerAgent = new AgentServiceRegistration() { Check = httpCheck, Checks = new[] { httpCheck }, ID = serviceConfig.ServiceId,//一定要指定服务ID,否则每次都会创建一个新的服务节点 Name = serviceConfig.ServiceName, Address = serviceConfig.ServiceIP, Port = serviceConfig.ServicePort, Tags = new[] { $"urlprefix-/{serviceConfig.ServiceName}" }//添加 urlprefix-/servicename 格式的tag标签,以便Fabio识别 }; consulClient.Agent.ServiceRegister(registerAgent).Wait();//服务启动时注册,使用Consul API进行注册(HttpClient发起) lifetime.ApplicationStopped.Register(() => { consulClient.Agent.ServiceDeregister(registerAgent.ID).Wait();//服务器停止时取消注册 }); return app; } }
在Startup中添加注册代码
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } //app.UseHttpsRedirection(); //DefaultFilesOptions defaultFilesOptions = new DefaultFilesOptions(); //defaultFilesOptions.DefaultFileNames.Clear(); //defaultFilesOptions.DefaultFileNames.Add("Index.html"); //app.UseDefaultFiles(defaultFilesOptions); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); var serviceConfig = Configuration.GetSection("ConsulConfig").Get<ServiceConfig>(); app.RegisterConsul(lifetime, serviceConfig); app.UseEndpoints(endpoints => { endpoints.MapDefaultControllerRoute(); endpoints.MapRazorPages(); }); }
发布启动后,可见以下注册成功的服务
点击pudefu.web(服务名称)这个服务可以查看服务详细信息
服务健康检查成功:
服务健康检查失败: