服务器之家

服务器之家 > 正文

详解SpringCloud eureka服务状态监听

时间:2021-05-18 11:07     来源/作者:时光沉旧了少年

一.前言

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

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

详解SpringCloud eureka服务状态监听

二.事件解析

事件列表

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

详解SpringCloud eureka服务状态监听

  • eurekainstancecanceledevent: 服务下线事件
  • eurekainstanceregisteredevent: 服务注册事件
  • eurekainstancerenewedevent: 服务续约事件
  • eurekaregistryavailableevent: eureka注册中心启动事件
  • eurekaserverstartedevent: eureka server启动时间

源码分析

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

续约事件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@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);
}
注册事件
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@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));
}

事件监听

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
@component
public 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的事件,如下配置即可:

?
1
2
3
4
5
@eventlistener(condition = "#event.replication==false")
public void listen(eurekainstancerenewedevent event) {
 // 服务续约
 logger.info(">>>>>>>>>>>>>>>server续约:" + event.getserverid());
}

github代码,点我

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

原文链接:https://segmentfault.com/a/1190000015681160

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总
苹果12mini价格表官网报价 iPhone12mini全版本价格汇总 2020-11-13
2021德云社封箱演出完整版 2021年德云社封箱演出在线看
2021德云社封箱演出完整版 2021年德云社封箱演出在线看 2021-03-15
返回顶部