详解SpringCloud eureka服务状态监听

网友投稿 520 2023-01-25


详解SpringCloud eureka服务状态监听

一.前言

近期由于公司不同平台项目之间的业务整合,需要做到相互访问! 每个平台均有自己的注册中心和服务,且注册中心相互之间并没有相互注册!

借助spring的事件监听,在eureka-server端监听服务注册,将所有服务的ip和port存放至redis库,然后让其他平台服务通过redis库获取ip和端口号,进而进行http调用.结构图如下:

二.事件解析

事件列表

在org.springframework.cloud.netflix.eureka.server.event包下会发现如下类:

EurekaInstanceCanceledEvent: 服务下线事件

EurekaInstanceRegisteredEvent: 服务注册事件

http://EurekaInstanceRenewedEvent: 服务续约事件

EurekaRegistryAvailableEvent: eureka注册中心启动事件

EurekaServerStartedEvent: eureka server启动时间

源码分析

打开org.springframework.cloud.netflix.eureka.server.InstanceRegistry类,会发现当eureka服务续约、注册、取消等时,spring会publish不同的事件,对应的事件类就是上面的列表.

http://

续约事件

@Override

public boolean renew(final String appName, final String serverId,

boolean isReplication) {

log("renew " + appName + " serverId " + serverId + ", isReplication {}"

+ isReplication);

List applications = getSortedApplications();

for (Application input : applications) {

if (input.getName().equals(appName)) {

InstanceInfo instance = null;

for (InstanceInfo info : input.getInstances()) {

if (info.getId().equals(serverId)) {

instance = info;

break;

}

}

// 发布续约事件

publishEvent(new EurekaInstanceRenewedEvent(this, appName, serverId,

instance, isReplication));

break;

}

}

return super.renew(appName, serverId, isReplication);

}

注册事件

@Override

public void register(InstanceInfo info, int leaseDuration, boolean isReplication) {

handleRegistration(info, leaseDuration, isReplication);

super.register(info, leaseDuration, isReplication);

}

private void handleRegistration(InstanceInfo info, int leaseDuration,

boolean isReplication) {

log("register " + info.getAppName() + ", vip " + info.getVIPAddress()

+ ", leaseDuration " + leaseDuration + ", isReplication "

+ isReplication);

// 发布注册事件

publishEvent(new EurekaInstanceRegisteredEvent(this, info, leaseDuration,

isReplication));

}

事件监听

通过上面的源码追溯,我们已经得到对应的事件类了,所以现在要做的仅仅是监听对应的事件即可,至此已经完成了我们所需要对事件监听后的业务处理!

@Component

public class EurekaStateChangeListener {

@Value("${iptable.platform}")

private String platform;

@Autowired

private RedisTemplate redisTemplate;

private static Logger logger = LoggerFactory.getLogger(EurekaStateChangeListener.class);

private static final String COLON = ":";

@EventListener//(condition = "#event.replication==false")

public void listen(EurekaInstanceCanceledEvent eurekaInstanceCanceledEvent) {

// 服务断线事件

String appName = eurekaInstanceCanceledEvent.getAppName();

String serverId = eurekaInstanceCanceledEvent.getServerId();

Objects.requireNonNull(appName, "服务名不能为空!");

SetOperations opsForSet = redisTemplate.opsForSet();

opsForSet.remove((platform + appName).toLowerCase(), serverId);

logger.info(">>>>>>> 失效服务:{},已被剔除!", serverId);

}

@EventListener//(condition = "#event.replication==false")

public void listen(EurekaInstanceRegisteredEvent event) {

// 服务注册

InstanceInfo instanceInfo = event.getInstanceInfo();

String appName = instanceInfo.getAppName();

Objects.requireNonNull(appName, "服务名不能为空!");

SetOperations opsForSet = redisTemplate.opsForSet();

opsForSet.add((platform + appName).toLowerCase(), instanceInfo.getIPAddr() + COLON +HIhdhwIw instanceInfo.getPort());

logger.info(">>>>>>> 服务名:{},端口号:{},已缓存至redis", appName, instanceInfo.getPort());

}

@EventListener//(condition = "#event.replication==false")

public void listen(EurekaInstanceRenewedEvent event) {

// 服务续约

logger.info(">>>>>>>>>>>>>>>Server续约:" + event.getServerId());

}

@EventListener

public void listen(EurekaRegistryAvailableEvent event) {

// 注册中心启动

logger.info(">>>>>>>>>>>>>>>Server注册中心:" + event);

}

@EventListener

public void listen(EurekaServerStartedEvent event) {

// Server启动

logger.info(">>>>>>>>>>>>>>>Server启动:" + event);

}

}

注意事项

[ ] 版本问题:

当时项目组用的SpringCloud版本是Brixton.RELEASE,该版本有一个问题就是服务注册和下线并不会出发http://对应的事件,所以导致一直监听不到.解决的办法也很简单,只要升级版本即可,我已经升级到最新版本Finchley.RELEASE.

传送门,点我

[ ] 重复监听:

例如,在续约的时候,eureka会发出2条EurekaInstanceRenewedEvent事件,但是2条事件的属性却不一样!一个事件的属性replication为true,另外一个为false.如果我们只想处理replication=true的事件,如下配置即可:

@EventListener(condition = "#event.replication==false")

public void listen(EurekaInstanceRenewedEvent event) {

// 服务续约

logger.info(">>>>>>>>>>>>>>>Server续约:" + event.getServerId());

}

github代码,点我


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:与主机连接共享文件夹(与主机连接共享文件夹怎么弄)
下一篇:Java操作文件输出为字符串以及字符串输出为文件的方法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~