使用 Consul 集群实现容错
Achieve Fault Tolerance with Consul Cluster
我在本地主机中使用不同的端口创建了 consul
服务器集群。
我为此使用了以下命令。
服务器 1:
consul agent -server -bootstrap-expect=3 -data-dir=consul-data -ui -bind=127.0.0.1 -dns-port=8601 -http-port=8501 -serf-lan-port=8303 -serf-wan-port=8304 -server-port=8305 -node=node1
服务器 2:
consul agent -server -bootstrap-expect=3 -data-dir=consul-data2 -ui -bind=127.0.0.1 -dns-port=8602 -http-port=8502 -serf-lan-port=8306 -serf-wan-port=8307 -server-port=8308 -node=node2 -join=127.0.0.1:8303
服务器 3:
consul agent -server -bootstrap-expect=3 -data-dir=consul-data1 -ui -bind=127.0.0.1 -node=node3 -join=127.0.0.1:8303
然后我使用 spring 引导创建了 2 个微服务,分别称为 service_A
和 service_B
。
Service_B
调用 service_A
获取一些数据。
两种服务都在上述服务器之一注册。
在application.properties中:
spring.cloud.consul.port=8501 #For service_A
spring.cloud.consul.port=8502 #For service_B
这很好用,因为 Service_B 发现 Service_A 没有任何问题。
现在,当我终止 service_A
注册的领事服务器时,系统无法给出结果,因为 Service_B
找不到 Service_A
。
我应该如何让这个系统容错,这意味着即使 consul 服务器发生故障,注册到该服务器的服务也会自动注册到集群中可用的另一台服务器。
另外我还想知道consul是如何在服务注册和发现上实现高可用和容错的。希望你能回答问题。
显然,您可以在本地机器上部署一个 consul 集群,但您不能期望在同一台本地机器上有任何弹性机制或容错。这是因为您的 spring 服务 (service_A & service_B) 已配置为识别 bootstrap.yml 下给定领事服务器端口中 运行 的领事服务器(默认 8500)。
spring:
cloud:
consul:
config:
watch:
enabled: true
port: 8500
discovery:
instanceId: ${spring.application.name}:${random.value}
所以每个服务都会发现运行8500端口下的consul服务器(你可以随意更改)。如果您 运行 在同一台本地机器上连接您的 consul 集群,您不能为每个需要识别的集群节点分配相同的端口号 (8500)。相同ip地址下运行会有所不同。为此,您需要将每个 consul 节点部署在具有相同端口号 8500 的不同 IP 地址下。
8301是serf LAN端口,用来处理局域网中的gossip。即使这个端口在每个节点中都可以相同,以保持集群互连。
实现此目的的最简单方法是在 AWS VPC 中使用私有子网。
然后您可以为每个子网节点分配单独的配置,每个服务器节点具有相同的端口号,以便它可以被您的 services_A & service_B 和 识别@EnableDiscoveryClient 注解.
我在本地主机中使用不同的端口创建了 consul
服务器集群。
我为此使用了以下命令。
服务器 1:
consul agent -server -bootstrap-expect=3 -data-dir=consul-data -ui -bind=127.0.0.1 -dns-port=8601 -http-port=8501 -serf-lan-port=8303 -serf-wan-port=8304 -server-port=8305 -node=node1
服务器 2:
consul agent -server -bootstrap-expect=3 -data-dir=consul-data2 -ui -bind=127.0.0.1 -dns-port=8602 -http-port=8502 -serf-lan-port=8306 -serf-wan-port=8307 -server-port=8308 -node=node2 -join=127.0.0.1:8303
服务器 3:
consul agent -server -bootstrap-expect=3 -data-dir=consul-data1 -ui -bind=127.0.0.1 -node=node3 -join=127.0.0.1:8303
然后我使用 spring 引导创建了 2 个微服务,分别称为 service_A
和 service_B
。
Service_B
调用 service_A
获取一些数据。
两种服务都在上述服务器之一注册。
在application.properties中:
spring.cloud.consul.port=8501 #For service_A
spring.cloud.consul.port=8502 #For service_B
这很好用,因为 Service_B 发现 Service_A 没有任何问题。
现在,当我终止 service_A
注册的领事服务器时,系统无法给出结果,因为 Service_B
找不到 Service_A
。
我应该如何让这个系统容错,这意味着即使 consul 服务器发生故障,注册到该服务器的服务也会自动注册到集群中可用的另一台服务器。
另外我还想知道consul是如何在服务注册和发现上实现高可用和容错的。希望你能回答问题。
显然,您可以在本地机器上部署一个 consul 集群,但您不能期望在同一台本地机器上有任何弹性机制或容错。这是因为您的 spring 服务 (service_A & service_B) 已配置为识别 bootstrap.yml 下给定领事服务器端口中 运行 的领事服务器(默认 8500)。
spring:
cloud:
consul:
config:
watch:
enabled: true
port: 8500
discovery:
instanceId: ${spring.application.name}:${random.value}
所以每个服务都会发现运行8500端口下的consul服务器(你可以随意更改)。如果您 运行 在同一台本地机器上连接您的 consul 集群,您不能为每个需要识别的集群节点分配相同的端口号 (8500)。相同ip地址下运行会有所不同。为此,您需要将每个 consul 节点部署在具有相同端口号 8500 的不同 IP 地址下。
8301是serf LAN端口,用来处理局域网中的gossip。即使这个端口在每个节点中都可以相同,以保持集群互连。
实现此目的的最简单方法是在 AWS VPC 中使用私有子网。
然后您可以为每个子网节点分配单独的配置,每个服务器节点具有相同的端口号,以便它可以被您的 services_A & service_B 和 识别@EnableDiscoveryClient 注解.