Eureka 1.1.4 版本 datacenter 的一个重要 bug

本贴最后更新于 2972 天前,其中的信息可能已经时异事殊

最近项目中在使用eureka作为服务发现框架,但是升级到1.1.4版本后,出现了启动eureka,服务每一分钟就上线下线一次的情况

github上已经向开发团队提交了bug:https://github.com/spring-cloud/spring-cloud-netflix/issues/1321

 

There seems to be a problem with public EIP address association not being correctly updated when a new AWS server starts and has a new Eureka server starting with it. When the server starts up, it correctly registers itself

 

2016-09-06 15:55:29.040  WARN 3399 --- [Thread-10] com.netflix.eureka.aws.EIPManager        : The selected EIP 54.67.102.122 is associated with another instance i-0666b391 according to AWS, hence skipping this
2016-09-06 15:55:29.628  INFO 3399 --- [Thread-10] com.netflix.eureka.aws.EIPManager        :

Associated i-25f11391 running in zone: us-west-1c to elastic IP: X.X.X.X

But, every minute after that we get the following log entry:

2016-09-06 16:24:55.568  INFO 3399 --- [Eureka-EIPBinder] c.n.e.r.PeerAwareInstanceRegistryImpl    : Got 1 instances from neighboring DS node
2016-09-06 16:24:55.568  INFO 3399 --- [Eureka-EIPBinder] c.n.e.r.PeerAwareInstanceRegistryImpl    : Renew threshold is: 1
2016-09-06 16:24:55.568  INFO 3399 --- [Eureka-EIPBinder] c.n.e.r.PeerAwareInstanceRegistryImpl    : Priming AWS connections for all replicas..
2016-09-06 16:24:55.568  INFO 3399 --- [Eureka-EIPBinder] c.n.e.r.PeerAwareInstanceRegistryImpl    : No peers needed to prime.
2016-09-06 16:24:55.568  INFO 3399 --- [Eureka-EIPBinder] c.n.e.r.PeerAwareInstanceRegistryImpl    : Changing status to UP
2016-09-06 16:24:55.713  WARN 3399 --- [Eureka-EIPBinder] com.netflix.eureka.aws.EIPManager        : The selected EIP X.X.X.X is associated with another instance i-0666b391 according to AWS, hence skipping this
2016-09-06 16:24:55.804  INFO 3399 --- [Eureka-EIPBinder] com.netflix.eureka.aws.EIPManage

Debugging this, the call to isEIPBound() is always failing, and this is because the following is always null:

String myPublicIP = ((AmazonInfo) myInfo.getDataCenterInfo()).get(MetaDataKey.publicIpv4);

It looks like there is stale datacenterinfo and it never gets refreshed (from what I can tell) and there there are no settings available to have it refreshed automatically.

The odd side affect of this, and we noticed, is that the registry continually gets wiped, and reset causing obvious potential issues down stream for our clients.

有热心网友给出了临时解决方案:


@Configuration
@Slf4j
@ConditionalOnAwsCloudEnvironment
@EnableContextInstanceData
@Import(UtilAutoConfiguration.class)
@AutoConfigureAfter(UtilAutoConfiguration.class)
public class AwsInstanceConfig {
<span class="pl-k">@Value</span>(<span class="pl-s"><span class="pl-pds">"</span>${server.port:${SERVER_PORT:${PORT:8080}}}<span class="pl-pds">"</span></span>)
<span class="pl-k">int</span> nonSecurePort;

<span class="pl-k">@Value</span>(<span class="pl-s"><span class="pl-pds">"</span>${management.port:${MANAGEMENT_PORT:${server.port:${SERVER_PORT:${PORT:8080}}}}}<span class="pl-pds">"</span></span>)
<span class="pl-k">int</span> managementPort;

<span class="pl-k">@Value</span>(<span class="pl-s"><span class="pl-pds">"</span>${eureka.instance.hostname:${EUREKA_INSTANCE_HOSTNAME:}}<span class="pl-pds">"</span></span>)
<span class="pl-smi">String</span> hostname;

<span class="pl-k">@Autowired</span>
<span class="pl-smi">ConfigurableEnvironment</span> env;


<span class="pl-k">@Bean</span>
<span class="pl-k">public</span> <span class="pl-smi">EurekaInstanceConfigBean</span> <span class="pl-en">eurekaInstanceConfigBean</span>(<span class="pl-smi">InetUtils</span> <span class="pl-v">utils</span>) {
    log<span class="pl-k">.</span>info(<span class="pl-s"><span class="pl-pds">"</span>Setting AmazonInfo on EurekaInstanceConfigBean<span class="pl-pds">"</span></span>);
    <span class="pl-k">final</span> <span class="pl-smi">EurekaInstanceConfigBean</span> instance <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">EurekaInstanceConfigBean</span>(utils) {

        <span class="pl-k">@Scheduled</span>(<span class="pl-c1">initialDelay</span> <span class="pl-k">=</span> <span class="pl-c1">30000L</span>, <span class="pl-c1">fixedRate</span> <span class="pl-k">=</span> <span class="pl-c1">30000L</span>)
        <span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">refreshInfo</span>() {
            log<span class="pl-k">.</span>debug(<span class="pl-s"><span class="pl-pds">"</span>Checking datacenter info changes<span class="pl-pds">"</span></span>);
            <span class="pl-smi">AmazonInfo</span> newInfo <span class="pl-k">=</span> <span class="pl-smi">AmazonInfo</span><span class="pl-k">.</span><span class="pl-smi">Builder</span><span class="pl-k">.</span>newBuilder()<span class="pl-k">.</span>autoBuild(<span class="pl-s"><span class="pl-pds">"</span>eureka<span class="pl-pds">"</span></span>);
            <span class="pl-k">if</span> (<span class="pl-k">!</span><span class="pl-v">this</span><span class="pl-k">.</span>getDataCenterInfo()<span class="pl-k">.</span>equals(newInfo)) {
                log<span class="pl-k">.</span>info(<span class="pl-s"><span class="pl-pds">"</span>Updating datacenterInfo to {}<span class="pl-pds">"</span></span>, newInfo);
                ((<span class="pl-smi">AmazonInfo</span>) <span class="pl-v">this</span><span class="pl-k">.</span>getDataCenterInfo())<span class="pl-k">.</span>setMetadata(newInfo<span class="pl-k">.</span>getMetadata());
            }
        }

        <span class="pl-k">private</span> <span class="pl-smi">AmazonInfo</span> <span class="pl-en">getAmazonInfo</span>() {
            <span class="pl-k">return</span> (<span class="pl-smi">AmazonInfo</span>) getDataCenterInfo();
        }

        <span class="pl-k">@Override</span>
        <span class="pl-k">public</span> <span class="pl-smi">String</span> <span class="pl-en">getHostname</span>() {
            <span class="pl-smi">AmazonInfo</span> info <span class="pl-k">=</span> getAmazonInfo();
            <span class="pl-k">final</span> <span class="pl-smi">String</span> publicHostname <span class="pl-k">=</span> info<span class="pl-k">.</span>get(<span class="pl-smi">AmazonInfo</span><span class="pl-k">.</span><span class="pl-smi">MetaDataKey</span><span class="pl-k">.</span>publicHostname);
            <span class="pl-k">return</span> <span class="pl-v">this</span><span class="pl-k">.</span>isPreferIpAddress() <span class="pl-k">?</span>
                info<span class="pl-k">.</span>get(<span class="pl-smi">AmazonInfo</span><span class="pl-k">.</span><span class="pl-smi">MetaDataKey</span><span class="pl-k">.</span>localIpv4) <span class="pl-k">:</span>
                publicHostname <span class="pl-k">==</span> <span class="pl-c1">null</span> <span class="pl-k">?</span>
                    info<span class="pl-k">.</span>get(<span class="pl-smi">AmazonInfo</span><span class="pl-k">.</span><span class="pl-smi">MetaDataKey</span><span class="pl-k">.</span>localHostname) <span class="pl-k">:</span> publicHostname;
        }

        <span class="pl-k">@Override</span>
        <span class="pl-k">public</span> <span class="pl-smi">String</span> <span class="pl-en">getHostName</span>(<span class="pl-k">final</span> <span class="pl-k">boolean</span> <span class="pl-v">refresh</span>) {
            <span class="pl-k">return</span> getHostname();
        }

        <span class="pl-k">@Override</span>
        <span class="pl-k">public</span> <span class="pl-smi">String</span> <span class="pl-en">getHomePageUrl</span>() {
            <span class="pl-k">return</span> <span class="pl-v">super</span><span class="pl-k">.</span>getHomePageUrl();
        }

        <span class="pl-k">@Override</span>
        <span class="pl-k">public</span> <span class="pl-smi">String</span> <span class="pl-en">getStatusPageUrl</span>() {
            <span class="pl-smi">String</span> scheme <span class="pl-k">=</span> getSecurePortEnabled() <span class="pl-k">?</span> <span class="pl-s"><span class="pl-pds">"</span>https<span class="pl-pds">"</span></span> <span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>http<span class="pl-pds">"</span></span>;
            <span class="pl-k">return</span> scheme <span class="pl-k">+</span> <span class="pl-s"><span class="pl-pds">"</span>://<span class="pl-pds">"</span></span> <span class="pl-k">+</span> getHostname() <span class="pl-k">+</span> <span class="pl-s"><span class="pl-pds">"</span>:<span class="pl-pds">"</span></span>
                <span class="pl-k">+</span> managementPort <span class="pl-k">+</span> getStatusPageUrlPath();
        }

        <span class="pl-k">@Override</span>
        <span class="pl-k">public</span> <span class="pl-smi">String</span> <span class="pl-en">getHealthCheckUrl</span>() {
            <span class="pl-smi">String</span> scheme <span class="pl-k">=</span> getSecurePortEnabled() <span class="pl-k">?</span> <span class="pl-s"><span class="pl-pds">"</span>https<span class="pl-pds">"</span></span> <span class="pl-k">:</span> <span class="pl-s"><span class="pl-pds">"</span>http<span class="pl-pds">"</span></span>;
            <span class="pl-k">return</span> scheme <span class="pl-k">+</span> <span class="pl-s"><span class="pl-pds">"</span>://<span class="pl-pds">"</span></span> <span class="pl-k">+</span> getHostname() <span class="pl-k">+</span> <span class="pl-s"><span class="pl-pds">"</span>:<span class="pl-pds">"</span></span>
                <span class="pl-k">+</span> managementPort <span class="pl-k">+</span> getHealthCheckUrlPath();
        }
    };
    <span class="pl-smi">AmazonInfo</span> info <span class="pl-k">=</span> <span class="pl-smi">AmazonInfo</span><span class="pl-k">.</span><span class="pl-smi">Builder</span><span class="pl-k">.</span>newBuilder()<span class="pl-k">.</span>autoBuild(<span class="pl-s"><span class="pl-pds">"</span>eureka<span class="pl-pds">"</span></span>);
    log<span class="pl-k">.</span>info(<span class="pl-s"><span class="pl-pds">"</span>Info: {}<span class="pl-pds">"</span></span>, info);
    instance<span class="pl-k">.</span>setDataCenterInfo(info);
    instance<span class="pl-k">.</span>setNonSecurePort(<span class="pl-v">this</span><span class="pl-k">.</span>nonSecurePort);
    instance<span class="pl-k">.</span>setInstanceId(getDefaultInstanceId(<span class="pl-v">this</span><span class="pl-k">.</span>env));
    <span class="pl-k">if</span> (<span class="pl-v">this</span><span class="pl-k">.</span>managementPort <span class="pl-k">!=</span> <span class="pl-v">this</span><span class="pl-k">.</span>nonSecurePort <span class="pl-k">&amp;&amp;</span> <span class="pl-v">this</span><span class="pl-k">.</span>managementPort <span class="pl-k">!=</span> <span class="pl-c1">0</span>) {
        <span class="pl-k">if</span> (<span class="pl-smi">StringUtils</span><span class="pl-k">.</span>hasText(<span class="pl-v">this</span><span class="pl-k">.</span>hostname)) {
            instance<span class="pl-k">.</span>setHostname(<span class="pl-v">this</span><span class="pl-k">.</span>hostname);
        }
    }

    <span class="pl-k">return</span> instance;
}

}

netfix的贡献者已经在修复这个bug,预计下一个版本能解决:https://github.com/Netflix/eureka/pull/843

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 七牛云

    七牛云是国内领先的企业级公有云服务商,致力于打造以数据为核心的场景化 PaaS 服务。围绕富媒体场景,七牛先后推出了对象存储,融合 CDN 加速,数据通用处理,内容反垃圾服务,以及直播云服务等。

    26 引用 • 222 回帖 • 164 关注
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    176 引用 • 995 回帖 • 1 关注
  • 倾城之链
    23 引用 • 66 回帖 • 138 关注
  • GitHub

    GitHub 于 2008 年上线,目前,除了 Git 代码仓库托管及基本的 Web 管理界面以外,还提供了订阅、讨论组、文本渲染、在线文件编辑器、协作图谱(报表)、代码片段分享(Gist)等功能。正因为这些功能所提供的便利,又经过长期的积累,GitHub 的用户活跃度很高,在开源世界里享有深远的声望,并形成了社交化编程文化(Social Coding)。

    209 引用 • 2031 回帖
  • Ruby

    Ruby 是一种开源的面向对象程序设计的服务器端脚本语言,在 20 世纪 90 年代中期由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)设计并开发。在 Ruby 社区,松本也被称为马茨(Matz)。

    7 引用 • 31 回帖 • 212 关注
  • App

    App(应用程序,Application 的缩写)一般指手机软件。

    91 引用 • 384 回帖
  • Electron

    Electron 基于 Chromium 和 Node.js,让你可以使用 HTML、CSS 和 JavaScript 构建应用。它是一个由 GitHub 及众多贡献者组成的活跃社区共同维护的开源项目,兼容 Mac、Windows 和 Linux,它构建的应用可在这三个操作系统上面运行。

    15 引用 • 136 回帖 • 1 关注
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 69 关注
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1433 引用 • 10052 回帖 • 483 关注
  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    117 引用 • 99 回帖 • 224 关注
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    34 引用 • 467 回帖 • 740 关注
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    30 引用 • 123 回帖 • 1 关注
  • WebSocket

    WebSocket 是 HTML5 中定义的一种新协议,它实现了浏览器与服务器之间的全双工通信(full-duplex)。

    48 引用 • 206 回帖 • 346 关注
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    12 引用 • 52 回帖 • 84 关注
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    70 引用 • 533 回帖 • 778 关注
  • Laravel

    Laravel 是一套简洁、优雅的 PHP Web 开发框架。它采用 MVC 设计,是一款崇尚开发效率的全栈框架。

    20 引用 • 23 回帖 • 725 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    565 引用 • 3532 回帖
  • Swift

    Swift 是苹果于 2014 年 WWDC(苹果开发者大会)发布的开发语言,可与 Objective-C 共同运行于 Mac OS 和 iOS 平台,用于搭建基于苹果平台的应用程序。

    36 引用 • 37 回帖 • 534 关注
  • 单点登录

    单点登录(Single Sign On)是目前比较流行的企业业务整合的解决方案之一。SSO 的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

    9 引用 • 25 回帖
  • 链滴

    链滴是一个记录生活的地方。

    记录生活,连接点滴

    152 引用 • 3780 回帖 • 1 关注
  • FlowUs

    FlowUs.息流 个人及团队的新一代生产力工具。

    让复杂的信息管理更轻松、自由、充满创意。

    1 引用
  • 学习

    “梦想从学习开始,事业从实践起步” —— 习近平

    168 引用 • 504 回帖
  • WebComponents

    Web Components 是 W3C 定义的标准,它给了前端开发者扩展浏览器标签的能力,可以方便地定制可复用组件,更好的进行模块化开发,解放了前端开发者的生产力。

    1 引用 • 2 关注
  • 自由行
    3 关注
  • CAP

    CAP 指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可兼得。

    11 引用 • 5 回帖 • 606 关注
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    130 引用 • 793 回帖
  • OpenResty

    OpenResty 是一个基于 NGINX 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

    17 引用 • 47 关注