

.NET Core + Consul 服务注册与发现
source link: https://www.tuicool.com/articles/Fnyu6ra
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Consul 介绍
在分布式架构中,服务治理是必须面对的问题,如果缺乏简单有效治理方案,各服务之间只能通过人肉配置的方式进行服务关系管理,当遇到服务关系变化时,就会变得极其麻烦且容易出错。
Consul 是一个用来实现分布式系统服务发现与配置的开源工具。它内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如 ZooKeeper 等),使用起来也较为简单。 如果你想和更多 Consul 技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态 。
Consul 架构
Consul 集群支持多数据中心,在上图中有两个 DataCenter,他们通过 Internet 互联,为了提高通信效率,只有 Server 节点才加入跨数据中心的通信。在单个数据中心中,Consul 分为 Client 和 Server 两种节点(所有的节点也被称为 Agent),Server 节点保存数据,Client 负责健康检查及转发数据请求到 Server,本身不保存注册信息;Server 节点有一个 Leader 和多个 Follower,Leader 节点会将数据同步到 Follower,Server 节点的数量推荐是3个或者5个,在 Leader 挂掉的时候会启动选举机制产生一个新 Leader。
Consul 集群搭建
这里使用 Docker 搭建 3个 Server 节点 + 1 个 Client 节点,API 服务通过 Client 节点进行服务注册和发现。
从 Docker Hub 拉取 Consul 镜像
docker pull consul
启动 3个 Server 节点 + 1 个 Client 节点
// Server 节点 1 docker run --name cs1 -p 8500:8500 -v /data/cs1:/data consul agent -server -bind 172.17.0.2 -node consul-server-1 -data-dir /data -bootstrap-expect 3 -client 0.0.0.0 -ui // Server 节点 2 docker run --name cs2 -p 7500:8500 -v /data/cs2:/data consul agent -server -bind 172.17.0.3 -node consul-server-2 -data-dir /data -bootstrap-expect 3 -client 0.0.0.0 -ui -join 172.17.0.2 // Server 节点 3 docker run --name cs3 -p 6500:8500 -v /data/cs3:/data consul agent -server -bind 172.17.0.4 -node consul-server-3 -data-dir /data -bootstrap-expect 3 -client 0.0.0.0 -ui -join 172.17.0.2 // Client 节点 1 docker run --name cc1 -p 5500:8500 -v /data/cc1:/data consul agent -bind 172.17.0.5 -node consul-client-1 -data-dir /data -client 0.0.0.0 -ui -join 172.17.0.2
参数说明(–name、-p、-v 为 Docker 相关参数):
集群状态
cs1 为容器名称,任意一个即可
查看节点状态和类型
docker exec -t cs1 consul members
当前为3 个 Server 类型节点 ,1 个 Client 类型节点。
查看 Server 节点类型
docker exec -t cs1 consul operator raft list-peers
当前为 consul-server-1 为 leader,可以测试将 consul-server-1 kill 观察 leader 的重新选举。
通过 http://192.168.124.8:8500 UI 界面查看 Consul 节点状态如下::7500、:6500、:5500 均可,192.168.124.8 是当前主机网络的 IPv4 地址。
.NET Core 接入 Consul
1、创建 .NET Core WebAPI 服务 ServiceA(2个实例) 和 ServiceB
2、Nuget 安装 Consul
3、注册到 Consul 的核心代码如下( 源码下载 ):
public static class ConsulBuilderExtensions { public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IApplicationLifetime lifetime, ConsulOption consulOption) { var consulClient = new ConsulClient(x => { // consul 服务地址 x.Address = new Uri(consulOption.Address); }); var registration = new AgentServiceRegistration() { ID = Guid.NewGuid().ToString(), Name = consulOption.ServiceName,// 服务名 Address = consulOption.ServiceIP, // 服务绑定IP Port = consulOption.ServicePort, // 服务绑定端口 Check = new AgentServiceCheck() { DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务启动多久后注册 Interval = TimeSpan.FromSeconds(10),//健康检查时间间隔 HTTP = consulOption.ServiceHealthCheck,//健康检查地址 Timeout = TimeSpan.FromSeconds(5) } }; // 服务注册 consulClient.Agent.ServiceRegister(registration).Wait(); // 应用程序终止时,服务取消注册 lifetime.ApplicationStopping.Register(() => { consulClient.Agent.ServiceDeregister(registration.ID).Wait(); }); return app; } }
4、添加配置如下:
"ServiceName": "ServiceA", "ServiceIP": "192.168.124.8", "ServicePort": 8000, "ServiceHealthCheck": "http://192.168.124.8:8000/healthCheck", "ConsulAddress": "http://192.168.124.8:8500"
5、注册成功结果如下:
6、ServiceB 调用 ServiceA 接口
ServiceB 通过 ConsulClient 进行服务发现,获取到 ServiceA 的地址,然后随机任意一台进行请求,核心代码如下:
var url = _configuration["ConsulAddress"].ToString(); using (var consulClient = new ConsulClient(a => a.Address = new Uri(url))) { var services = consulClient.Catalog.Service("ServiceA").Result.Response; if (services != null && services.Any()) { // 模拟随机一台进行请求,这里只是测试,可以选择合适的负载均衡工具或框架 Random r = new Random(); int index = r.Next(services.Count()); var service = services.ElementAt(index); using (HttpClient client = new HttpClient()) { var response = await client.GetAsync($"http://{service.ServiceAddress}:{service.ServicePort}/values/test"); var result = await response.Content.ReadAsStringAsync(); return result; } } }
7、多次调用 ServiceB 接口结果如下:
参考链接
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK