Spring Cloud Finchley版中Consul多实例注册的问题处理

由于Spring Cloud对Etcd的支持一直没能从孵化器中出来,所以目前来说大多用户还在使用Eureka和Consul,之前又因为Eureka 2.0不在开源的消息,外加一些博眼球的标题党媒体使得Eureka的用户有所减少,所以,相信在选择Spring Cloud的用户群体中,应该有不少用户会选择Consul来做服务注册与发现。 本文就来说一下,当我们使用Spring Cloud最新的Finchley版 + Consul 1.2.x时候最严重的一个坑:多实例注册的问题。

问题解读

问题:该问题可能在开发阶段不一定会发现,但是在线上部署多实例的时候,将会发现Consul中只有一个实例。

原因:造成该问题的主要原因是Spring Cloud Consul在注册的时候实例名(InstanceId)采用了:“服务名-端口号”(即: {spring.application.name}-{server.port})的值,可以看到这个实例名如果不改变端口号的情况下,实例名都是相同的。如果熟悉Spring Cloud Consul的读者,可能会问老版本也是这个规则,怎么没有这个问题呢?。主要是由于Consul对实例唯一性的判断标准也有改变,在老版本的Consul中,对于实例名相同,但是服务地址不同,依然会认为是不同的实例。在Consul 1.2.x中,服务实例名成为了集群中的唯一标识,所以,也就导致了上述问题。

解决方法

既然知道了原因,那么我们要解决它就可以有的放矢了。下面就来介绍两个具体的解决方式:

方法一:通过配置属性指定新的规则

下面举个例子,通过 spring.cloud.consul.discovery.instance-id参数直接来配置实例命名规则。这里比较粗暴的通过随机数来一起组织实例名。当然这样的组织方式并不好,因为随机数依然有冲突的可能,所以您还可以用更负责的规则来进行组织实例名。

spring.cloud.consul.discovery.instance-id=${spring.application.name}-${random.int[10000,99999]}

方法二:通过扩展 ConsulServiceRegistry来重设实例名

由于通过配置属性的方式对于定义实例名的能力有限,所以我们希望可以用更灵活的方式来定义。这时候我们就可以通过重写 ConsulServiceRegistryregister方法来修改。比如下面的实现:

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

}

上面通过拼接“服务名”-“ip地址”-“端口号”的方式,构造了一个绝对唯一的实例名,这样就可以让每个服务实例都能正确的注册到Consul上了。

原文发布于微信公众号 - 程序猿DD(didispace)

原文发表时间:2018-08-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏好好学java的技术栈

springmvc带你学:带你入门

传统MVC——>JSPModel2——>Front Controller + Application Controller + Page Controller ...

10410
来自专栏程序猿DD

Spring Cloud构建微服务架构:服务容错保护(Hystrix断路器)【Dalston版】

前言 在前两篇Spring Cloud构建微服务架构:服务容错保护(Hystrix服务降级)【Dalston版】和Spring Cloud构建微服务架构:服务容...

19960
来自专栏IT技术精选文摘

JMeter最多可以模拟多少测试用户数?

本文我们将讨论一个确切说没有准确答案的问题 - 即我们使用Apache JMeter™最多可以模拟多少用户来做测试? 像JMeter本身的限制一样,这样的限制因...

92370
来自专栏情情说

《深入实践Spring Boot》阅读笔记之三:核心技术源代码分析

上篇文章总结了《深入实践Spring Boot》的第二部分,本篇文章总结第三部分,也是最后一部分。这部分主要讲解核心技术的源代码分析,因为篇幅和能力原因,分析的...

55290
来自专栏xingoo, 一个梦想做发明家的程序员

Tomcat 6 --- 使用Jasper引擎解析JSP

熟悉JAVA web开发的朋友都知道JSP会被转换成java文件(预编译),然后编译成class使用,即按照JSP-->java-->class的过程进行编译...

31670
来自专栏Rainbond开源「容器云平台」

【Docker】Flume+Kafka收集Docker容器内分布式日志应用实践

21060
来自专栏LanceToBigData

Spring(一)Spring的第一滴血

前言   开始工作了,但是一进来公司本来是做爬虫和数据分析的,但是走了一个后端的,导致我必须要去顶替他的工作。因为这个项目使用的是Spring、   Sprin...

27560

在Debian 7上安装PocketMine服务器

PocketMine是适用于我的世界Android和iOS版本的第三方服务器。该服务支持插件,允许您与其他人自定义游戏。本指南详细介绍了在运行Debian 7的...

19840
来自专栏运维一切

MESOS集群高可用部署 原

memsos一般需要奇数台的机器比如1 3 5 7….来组成集群,他的容灾依赖zookeeper集群。

12530
来自专栏Laoqi's Linux运维专列

ssh访问控制,多次失败登录即封掉IP,防止暴力破解

近期一直发现站内的流量和IP不太正常,读取/var/log/secure 很多失败的登录信息!必须要整个方法整死他们,虽然我已经把ssh port修改为了XXX...

52640

扫码关注云+社区

领取腾讯云代金券