一.前言
近期由于公司不同平台项目之间的业务整合,需要做到相互访问! 每个平台均有自己的注册中心和服务,且注册中心相互之间并没有相互注册!
借助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