SpringBoot2.x 內建Consul負載均衡多執行個體注冊
- 原理
- 解決方案(2種)
-
- 解決方案一
-
- 自定義ConsulServiceRegistry
- 開啟心跳檢測
- 解決方案二
-
- 直接修改執行個體ID
- 參考
原理
- 問題:問題在多個執行個體注冊時出現。如果不解決将會出現執行個體覆寫的情況,實作不了負載均衡。
- 原因:根據官網描述:Consul 的注冊機制,預設是Spring Cloud Consul在注冊的時候執行個體名(InstanceId)采用了:“服務名-端口号”(即:{spring.application.name}-{server.port})的值,可以看到這個執行個體名如果不改變端口号的情況下,執行個體名都是相同的。
-
官網描述
By default a consul instance is registered with an ID that is equal to its Spring Application Context ID. By default, the Spring Application Context ID is ${spring.application.name}:comma,separated,profiles: ${server.port}. For most cases, this will allow multiple instances of one service to run on one machine. If further uniqueness is required, Using Spring Cloud you can override this by providing a unique identifier in spring.cloud.consul.discovery.instanceId. For example:
- Consul 舊版本機制:熟悉Spring Cloud Consul的讀者,可能會問老版本也是這個規則,怎麼沒有這個問題呢?。主要是由于Consul對執行個體唯一性的判斷标準也有改變,在老版本的Consul中,對于執行個體名相同,但是服務位址不同,依然會認為是不同的執行個體。在Consul 1.2.x中,服務執行個體名成為了叢集中的唯一辨別,是以,也就導緻了上述問題。
解決方案(2種)
解決方案一
自定義ConsulServiceRegistry
@Configuration
public class MyConsulServiceRegistry extends ConsulServiceRegistry {
/**
* 參照源碼定義聲名
*/
@Autowired(required = false)
private TtlScheduler ttlScheduler;
public MyConsulServiceRegistry(ConsulClient client, ConsulDiscoveryProperties properties, TtlScheduler ttlScheduler, HeartbeatProperties heartbeatProperties) {
super(client, properties, ttlScheduler, heartbeatProperties);
}
@Override
public void register(ConsulRegistration reg) {
reg.getService().setId(reg.getService().getName() + "-" + reg.getService().getAddress() + "-" + reg.getService().getPort());
super.register(reg);
}
}
開啟心跳檢測
spring:
consul:
discovery:
heartbeat:
enabled: true
解決方案二
直接修改執行個體ID
spring.cloud.consul.discovery.instance-id=${spring.application.name}-${random.int[10000,99999]}
參考
本文章隻是對springboot2.內建consul 問題解決補充,感興趣的可以參考
[1]:Spring Cloud Finchley版中Consul多執行個體注冊的問題處理
[2]: Spring Cloud Consul 多執行個體注冊問題