好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

详解SpringCloud eureka服务状态监听

一.前言

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

借助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不同的事件,对应的事件类就是上面的列表.

续约事件

?

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

查看更多关于详解SpringCloud eureka服务状态监听的详细内容...

  阅读:47次