服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - 详解Spring Cloud Finchley版中Consul多实例注册的问题处理

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

2021-05-28 13:12翟永超 Java教程

这篇文章主要介绍了详解Spring Cloud Finchley版中Consul多实例注册的问题处理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

consul 简介

consul 具有以下性质:

  1. 服务发现:consul通过http 方式注册服务,并且服务与服务之间相互感应。
  2. 服务健康监测
  3. key/value 存储
  4. 多数据中心

consul可运行在mac windows linux 等机器上。

由于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 来重设实例名

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

?
1
2
3
4
5
6
7
8
9
10
11
12
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上了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:http://blog.didispace.com/Spring-Cloud-Finchley-Consul-InstanceId/

延伸 · 阅读

精彩推荐