失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > .NET Core + Consul 服务注册与发现

.NET Core + Consul 服务注册与发现

时间:2020-12-21 13:01:50

相关推荐

.NET Core + Consul 服务注册与发现

在分布式架构中,服务治理是必须面对的问题,如果缺乏简单有效治理方案,各服务之间只能通过人肉配置的方式进行服务关系管理,当遇到服务关系变化时,就会变得极其麻烦且容易出错。

Consul[1] 是一个用来实现分布式系统服务发现与配置的开源工具。它内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如 ZooKeeper 等),使用起来也较为简单。

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 节点

docker-compose.yaml如下:

version: '3'services:cs1:image: consulcommand: agent -server -client=0.0.0.0 -bootstrap-expect=3 -node=cs1 -data-dir=/datavolumes:- /usr/local/docker/consul/data/cs1:/datacs2:image: consulcommand: agent -server -client=0.0.0.0 -retry-join=cs1 -node=cs2 -data-dir=/datavolumes:- /usr/local/docker/consul/data/cs2:/datadepends_on:- cs1cs3:image: consulcommand: agent -server -client=0.0.0.0 -retry-join=cs1 -node=cs3 -data-dir=/datavolumes:- /usr/local/docker/consul/data/cs3:/datadepends_on:- cs1cc1:image: consulcommand: agent -client=0.0.0.0 -retry-join=cs1 -ui -node=cc1 -data-dir=/dataports:- 8500:8500volumes:- /usr/local/docker/consul/data/cc1:/datadepends_on:- cs2- cs3

主要参数说明:

集群状态

(e002ca62ac24 为容器名称,可通过 docker ps | grep consul 查看,选择任意一个即可)

查看节点状态和类型

docker exec -t e002ca62ac24 consul members

当前为3 个 Server 类型节点 ,1 个 Client 类型节点。

查看 Server 节点类型

docker exec -t e002ca62ac24 consul operator raft list-peers

当前为 cs1 为 leader,可以测试将 cs1 stop 观察 leader 的重新选举。

通过http://192.168.124.9:8500UI 界面查看 Consul 节点状态如下:(192.168.124.9 是 consul 容器外部访问 IP)

.NET Core 接入 Consul

创建 .NET Core WebAPI(3.1) 服务 ServiceA(2个实例) 和 ServiceB

NuGet 安装 Consul

注册到 Consul 的核心代码如下(源码下载[2]):

public static class ConsulBuilderExtensions{public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IHostApplicationLifetime lifetime, ConsulOption consulOption){var consulClient = new ConsulClient(x =>{x.Address = new Uri(consulOption.Address);});var registration = new AgentServiceRegistration(){ID = Guid.NewGuid().ToString(),Name = consulOption.ServiceName,// 服务名Address = consulOption.ServiceIP, // 服务绑定IPPort = 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;}}

添加配置如下:

"Consul": {"ServiceName": "service-a","ServiceIP": "192.168.124.11", // 当前服务访问 IP"ServicePort": 8000,"ServiceHealthCheck": "http://192.168.124.11:8000/healthCheck","Address": "http://192.168.124.9:8500"}

注册成功结果如下:

ServiceB 调用 ServiceA 接口

ServiceB 通过 ConsulClient 进行服务发现,获取到 ServiceA 的地址,然后随机请求请求任意一个实例,关键代码如下:

using (var consulClient = new ConsulClient(a => a.Address = new Uri(_consulOption.Address))){var services = consulClient.Catalog.Service("service-a").Result.Response;if (services != null && services.Any()){// 模拟随机一台进行请求,这里只是测试,可以选择合适的负载均衡框架var service = services.ElementAt(new Random().Next(services.Count()));var client = _httpClientFactory.CreateClient();var response = await client.GetAsync($"http://{service.ServiceAddress}:{service.ServicePort}/test/get");var result = await response.Content.ReadAsStringAsync();return result;}}

多次调用结果如下:

参考资料

[1]

Consul:https://www.consul.io/

[2]

源码下载:/beckjin/ConsulDotnetSamples

如果觉得《.NET Core + Consul 服务注册与发现》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。