首页 > 编程 > Java > 正文

详解SpringCloud eureka服务状态监听

2019-11-26 09:48:53
字体:
来源:转载
供稿:网友

一.前言

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

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

二.事件解析

事件列表

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

  • EurekaInstanceCanceledEvent: 服务下线事件
  • EurekaInstanceRegisteredEvent: 服务注册事件
  • EurekaInstanceRenewedEvent: 服务续约事件
  • EurekaRegistryAvailableEvent: eureka注册中心启动事件
  • EurekaServerStartedEvent: eureka server启动时间

源码分析

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

续约事件

 @Override public boolean renew(final String appName, final String serverId,   boolean isReplication) {  log("renew " + appName + " serverId " + serverId + ", isReplication {}"    + isReplication);  List<Application> 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)); }

事件监听

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

@Componentpublic class EurekaStateChangeListener { @Value("${iptable.platform}") private String platform;  @Autowired private RedisTemplate<String, String> 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<String, String> 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<String, String> opsForSet = redisTemplate.opsForSet();  opsForSet.add((platform + appName).toLowerCase(), instanceInfo.getIPAddr() + COLON + 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,该版本有一个问题就是服务注册和下线并不会出发对应的事件,所以导致一直监听不到.解决的办法也很简单,只要升级版本即可,我已经升级到最新版本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代码,点我

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表