一、Eureka原理粗讲

b832022a0d23183a47ef4de1f93cf0c5.jpg

二、Eureka几大事件

48dbd95a1290152a05a7efdfd334f682.jpg


EurekaInstanceCanceledEvent:失效事件。

EurekaInstanceRegisteredEvent:注册事件。

EurekaInstanceRenewedEvent:心跳事件。

EurekaRegistryAvailableEvent:可用事件。

EurekaServerStartedEvent:启动事件。


ApplicationListener:Spring事件监听器 服务扩展失效通知。


代码如下:代码文件在Eureka-server端

package com.github.wxiaoqi.security.center.listener;

import com.netflix.discovery.shared.Applications;
import com.netflix.eureka.EurekaServerContextHolder;
import com.netflix.eureka.registry.PeerAwareInstanceRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent;
import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent;
import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRenewedEvent;
import org.springframework.cloud.netflix.eureka.server.event.EurekaRegistryAvailableEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;

/**
 * 用于监听eureka服务停机通知
 * @Description:用于监听eureka服务停机通知
 * @Date:11:25 2017/11/10
 */
@Configuration
@EnableScheduling
public class EurekaInstanceCanceledListener implements ApplicationListener {
    private Logger log = LoggerFactory.getLogger(EurekaInstanceCanceledListener.class);
    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        // 服务挂掉事件
        if (applicationEvent instanceof EurekaInstanceCanceledEvent) {
            EurekaInstanceCanceledEvent event = (EurekaInstanceCanceledEvent) applicationEvent;
            // 获取当前Eureka实例中的节点信息
            PeerAwareInstanceRegistry registry = EurekaServerContextHolder.getInstance().getServerContext().getRegistry();
            Applications applications = registry.getApplications();
            // 遍历获取已注册节点中与当前失效节点ID一致的节点信息
            applications.getRegisteredApplications().forEach((registeredApplication) -> {
                registeredApplication.getInstances().forEach((instance) -> {
                    if (instance.getInstanceId().equals(event.getServerId())) {
                        log.info("服务:" + instance.getAppName() + " 挂啦。。。");
                        // // TODO: 2017/9/3 扩展消息提醒 邮件、手机短信、微信等
                    }
                });
            });
        }
        if (applicationEvent instanceof EurekaInstanceRegisteredEvent) {
            EurekaInstanceRegisteredEvent event = (EurekaInstanceRegisteredEvent) applicationEvent;
            log.info("服务:" + event.getInstanceInfo().getAppName() + " 注册成功啦。。。");
        }
        if (applicationEvent instanceof EurekaInstanceRenewedEvent) {
            EurekaInstanceRenewedEvent event = (EurekaInstanceRenewedEvent) applicationEvent;
            log.info("心跳检测服务:" + event.getInstanceInfo().getAppName() + "。。");
        }
        if (applicationEvent instanceof EurekaRegistryAvailableEvent) {
            log.info("服务 Aualiable。。");
        }
    }
}

测试效果:

1:启动Eureka-server

 9644aa06f3905cc34a51d38d0b91af7b.jpg

2:启动Eureka-client:user-center

 52fb99b960444b2a98b05b60ddd70de9.jpg

3:关闭Eureka-client:user-center

 467293d0417dc913219a7e23dd3f9e4d.jpg

三、Eureka常见问题

踢出已关停的节点

由于Eureka自我保护模式,以及心跳周期长的原因,常常会遇到Eureka Server不踢出已关停的节点的问题。


server端:

eureka:
  server:
    enable-self-preservation: false          # 设为false,关闭自我保护
    eviction-interval-timer-in-ms: 4000    # 清理间隔(单位毫秒,默认60*1000)

client端:

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
    healthcheck:
            enabled: true       # 开启健康检查(需要spring-boot-starter-actuator依赖)
  instance:
    lease-renewal-interval-in-seconds: 10     # 租期更新时间间隔(默认30秒)
    lease-expiration-duration-in-seconds: 30  # 租期到期时间(默认90秒)

多网卡环境下的IP选择问题

Eureka会选择IP合法(标准ipv4地址)、索引值最小(eth0,eht1中eth0优先)且不在忽略列表中(可在application配置文件中配置忽略哪些网卡)的网卡地址作为服务IP。

配置:(????)

eureka:
  instance:
    # 多网卡制定IP,docker部署推荐
    ip-address: 127.0.0.1              # 手动指定IP地址
    prefer-ip-address: true           # 注册时使用ip而不是主机名

服务感知慢

Eureka的wiki上有一句话,大意是一个服务启动后最长可能需要2分钟时间才能被其它服务感知。

eureka.instance.leaseRenewallntervallnSecods(在生产中,最好坚持使用默认值,因为在服务器内部有一些计算,他们对续约做出假设)。