Consul的多实例注册问题

公司终于要重构一个非常古老的项目了(之前我建议了好多次,也讨论了好多次,这次终于动工了),将其按照微服务方式搭建,采用spring cloud框架(之前已经在其它项目中使用了很久)
很期待此项目可以顺利实现,可以支撑未来的业务发展,然而这一次稍微来的晚了一些,我就要离开了。
走之前我还是站好最后一班岗,把新版工程的微服务架构搭建一下,并实现统一gateway入口路由和oauth认证逻辑还有Member用户中心微服务中必要的接口,算是遗产了。
按照我的习惯,只要是全新的项目,我将尽可能更新之前使用到的技术。
由于之前我们使用的是Eureka作为注册服务,而它在2.0宣布闭源,这个对今后会带来什么影响未知,所以我决定将新版工程架构注册服务迁移到Consul。
这不就遇到问题了……

问题描述

我有一个Member用户中心服务,当我在不同主机(不同ip地址)上运行两个Member微服务时,Consul中心只能看到一个服务实例。
第一反应,What!? 这个和我想象的完全不一样啊,这应该是默认功能啊,服务的多节点哪里去了!?如图:

我运行了两个实例,但只能看见一个

我这里的consul用的是1.3版本

问题原因

Consul团队具体怎么考虑这个实例名称生成规则的,我不是很清楚,但是问题就是因为它
https://github.com/spring-cloud/spring-cloud-consul/issues/318
一年多前开的issue竟然还没有关,问题就是instance id的默认组成规则是 application name - port
没有ip地址,所以当我启动Member服务时,虽然在不同主机上,但是端口相同,所以instance id是一样一样的😂
所以,我们只能看到最后启动的那个实例
虽然下面回复中,中国朋友(推断)给出了明确的问题所在和建议的解决方法,然而Consul开发团队还是继续坚持他们的想法(或是spring cloud discovery包没有及时更新!?,issue没有关可能consul团队问题更多一些,人家spring团队也只是整合而已啦),额~~~为什么不改,没有理解

解决办法

程序员DD给出了解决办法
顺便提及一句,程序员DD非常不错,值得关注

随机端口方式我就不说了,这个不可取,我没有用。

直接final way,重新实现ConsulServiceRegistry

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 调整consul服务注册实例名称
*
* @author gino
* Created on 2018/11/9
*/
@Configuration
public class MyConsulServiceRegistry extends ConsulServiceRegistry {

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);
}

}

没有什么好解释的,在此启动就有两个服务了,如图

两个服务,正常注册上了,红色区域就是我们要解决的问题最终结果。

总结

除了Consul中的一些小改变,其实每次Spring Cloud的版本升级(当前使用的Greenwich.M1)都会这样那样的问题,我们需要慢慢踩雷,慢慢成长。