一.前言
近期由于公司不同平臺項目之間的業務整合,需要做到相互訪問! 每個平臺均有自己的注冊中心和服務,且注冊中心相互之間并沒有相互注冊!
借助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