使⽤Consul实现服务发现:instance-id⾃定义(3种⽅式)
TIPS
本⽂基于Spring Cloud Hoxton,理论⽀持Spring Cloud所有版本。
本⽂探讨如何⾃定义微服务注册到Consul的InstanceId。
Consul把InstanceId作为唯⼀标识,⽽Spring Cloud Consul默认的InstanceId是${spring.application.name}-${server.port}。
这样导致的问题是:某个微服务即使有多个实例,只要端⼝相同,那么Consul上依然只会保留1条数据!要想解决这个问题,只需要让不同实例,拥有不同的InstanceId即可。
⽅式1:拼接随机值
添加配置:
spring:
cloud:
consul:
discovery:
instance-id: ${spring.application.name}-${server.port}-${random.long}
⽬前市⾯上的⼀些⽂章也是这么玩的。但这样做,在⼀些场景下还是有⼀点⼩问题的。
举个例⼦:假设某个微服务实例崩溃了,然后在很短的时间内(Consul还没来得及把这个实例删除);应⽤重启了,就会导致Consul上出现两条数据,但其实代表的是⼀个实例
(虽然过段时间后,Consul会把没⽤的实例删除,但在⼀段时间内出现2条数据还是很诡异的)。
TIPS
⽅式2:拼接机器唯⼀标识
讲到这⾥,聪明的同学⼀定会想到,⼀个合理的instanceid应该满⾜以下两点需求:
不同实例的instanceid不同;
相同实例启动多次,instanceid应该相同。
要想实现这两点诉求,只要在instanceid上加上机器的唯⼀标⽰就OK了,⽐如IP或者是主机名等等。
spring:
cloud:
consul:
discovery:
instance-id: ${spring.application.name}-${server.port}-${spring.cloud.client.hostname}
或者:
spring:
cloud:
consul:
discovery:
instance-id: ${spring.application.name}-${server.port}-${spring.cloud.client.ip-address}
TIPS
这⾥,${spring.cloud.client.hostname}以及${spring.cloud.client.ip-address},是利⽤了Spring Boot配置⽂件可以读取环境变量的特点。
你的应⽤只要集成Spring Boot Actuator,就可以通过/actuator/env查看所有环境变量啦!环境变量的Key值,都可以写到配置⽂件中。
⽅式3:代码扩展
如果上⾯两种⽅式依然满⾜不了你的需求,那么你还可以通过写代码的⽅式去扩展。
代码:
public class WiiConsulAutoRegistration extends ConsulAutoRegistration {
public WiiConsulAutoRegistration(NewService service, AutoServiceRegistrationProperties autoServiceRegistrationProperties, ConsulDiscoveryProperties properties, ApplicationContext context,
HeartbeatProperties heartbeatProperties, List<Co super(service, autoServiceRegistrationProperties, properties, context, heartbeatProperties, managementRegistrationCustomizers);
}
public static String getInstanceId(WiiProperties wiiProperties,
Environment environment) {
return String.format("%s-%s-%s",
}
}
配置:
@Configuration
public class XXXConfiguration {
spring怎么读取properties@Bean
public ConsulAutoRegistration consulRegistration(
AutoServiceRegistrationProperties autoServiceRegistrationProperties,
ConsulDiscoveryProperties properties,
ApplicationContext applicationContext,
ObjectProvider<List<ConsulRegistrationCustomizer>> registrationCustomizers,
ObjectProvider<List<ConsulManagementRegistrationCustomizer>> managementRegistrationCustomizers,
HeartbeatProperties heartbeatProperties) {
istration(autoServiceRegistrationProperties,
properties, applicationContext, IfAvailable(),
}
}
TIPS
这种⽅式更加灵活,你想怎么玩就怎么玩。你可以在InstanceId上拼接mac地址或者其他什么玩意⼉……不过,只是为了定制个唯⼀标⽰⽽已,这么玩成本有点
⾼了,我建议:如果没有不得已的苦衷,就甭折腾了。
我的个⼈项⽬Spring Cloud Wii(也就是现在的Spring Cloud Alibaba Sidecar)就是使⽤的这种⽅式⾃定义InstanceId的。但Wii之所以采⽤这种⽅式,是因为Wii
本⾝就要扩展WiiConsulAutoRegistration,定制⼀下InstanceId只是顺⼿⽽为。相关代码在这⾥,有兴
趣可以看下:github/eacdy/spring-cloud-
wii/blob/master/spring-cloud-wii/src/main/java/com/itmuch/wii/consul/WiiConsulAutoRegistration.java
未来...
本⽂⾸发
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论