最近项目中在使用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">&&</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
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于