問題小記(一):Eureka DS Replicas


最近工作中開始搭建工程,發現一個很迷惑的地方 DS Replicas。 之前接觸Eureka也只是簡單搭建。

現象描述:

eureka在k8s環境起了兩台。回家后本地搭建配置文件如下:application-peerA/peerB.yml,外加本地host修改。
application-peerA.yml


EUREKA_INSTANCE_HOSTNAME: peerA
EUREKA_SERVER: http://peerB:8081/eureka/,http://peerA:8080/eureka/
PORT: 8080

server:
  port: ${PORT}
spring:
  application:
    name: eureka-server
eureka:
  server:
    enable-self-preservation: false
    use-read-only-response-cache: false
    eviction-interval-timer-in-ms: 5000
  client:
    registry-fetch-interval-seconds: 5
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: ${EUREKA_SERVER:http://127.0.0.1:${server.port}/eureka/}
  instance:
    hostname: ${EUREKA_INSTANCE_HOSTNAME:${spring.application.name}}
    lease-renewal-interval-in-seconds: 5
    lease-expiration-duration-in-seconds: 10
    instance-id: ${EUREKA_INSTANCE_HOSTNAME:${spring.application.name}}:${server.port}@${random.long(1000000,9999999)}

application-peerB.yml

EUREKA_INSTANCE_HOSTNAME: peerB
EUREKA_SERVER: http://peerA:8080/eureka/,http://peerB:8081/eureka/
PORT: 8081

server:
  port: ${PORT}
spring:
  application:
    name: eureka-server
eureka:
  server:
    #關閉自我保護
    enable-self-preservation: false
    use-read-only-response-cache: false
    #設置自動清理時間
    eviction-interval-timer-in-ms: 5000
  client:
    registry-fetch-interval-seconds: 5
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: ${EUREKA_SERVER:http://127.0.0.1:${server.port}/eureka/}
  instance:
    hostname: ${EUREKA_INSTANCE_HOSTNAME:${spring.application.name}}
    lease-renewal-interval-in-seconds: 5
    lease-expiration-duration-in-seconds: 10
    instance-id: ${EUREKA_INSTANCE_HOSTNAME:${spring.application.name}}:${server.port}@${random.long(1000000,9999999)}

本地host修改如下。

127.0.0.1  peerB
127.0.0.1  peerA

兩台服務啟動效果如下,只看到peerA頁面下DS Replicas只有peerB, peerB下的DS只有peerA。
image


線上環境中兩台下面都是這樣的。peerA和peerB。


image

現象清楚了,就是本地模擬環境上k8s兩台服務時候, DS Replicas展示不一樣。

探究現象背后的原因

因為對SpringBoot包括Eureka沒有特別深入學習過,所以只能自己嘗試看代碼發現問題。

localhost:8080頁面是怎么渲染出來的

1.在IDEA的幫助下找到了這個接口對應的handler,可以發現兩個結論:1. EurekaController就是我們要找的;2.可以通過eureka.dashboard.path配置修改eureka dashboard的地址,默認是/。
image

2.然后就在該Controller中驗證了猜想。可以得出結論:方法返回值為String,應該是使了JSP或Freemarker等模板。
image

3.通過IDEA的幫助,定位Class所在包,如左圖。可以得出結論:1.確實是使用了freemarker模板;2.status.ftlh就是我們要找的首頁模板了。
image

4.發現status.ftlh中沒有DS Replicas關鍵字,在navbar.ftlh中找到的。可以得出結論:replicas這個就是頁面渲染使用到的數據,是一個列表。
image

5.於是返回RequestMapping中查找replicas是怎么填充的。可以猜測:PeerEurekaNode這個對象有幾個決定頁面的DS Replicas。
image


6.到這里也只是發現了DS Replicas和PeerEurekaNode有很大關系,具體是什么還完全沒頭緒。

PeerEurekaNode是啥?

上一步分析到這里。通過分析調用關系,發現:serverContext是DefaultEurekaServerContext,PeerEurekaNodes具體是RefreshablePeerEurekaNodes。下面只要分析RefreshablePeerEurekaNodes的getPeerNodesView方法即可。
image


1.RefreshablePeerEurekaNodes繼承自PeerEurekaNodes,其內部維護一個列表,PeerEurekaNode的集合。 首頁用到的就是這個列表的副本。這個屬性只有在updatePeerEurekaNodes方法中有修改操作。
image


2.IDEA中查看上述方法只有如下兩處調用:第二處可以理解為是環境刷新時候調用,第一處才是最常調用的地方。
image


3.start方法是DefaultEurekaServerContext對象生成完畢后調用,只調用一次。start方法內部用單個專門線程去定期調用一次updatePeerEurekaNodes方法,頻率為固定10分鍾。
image


4. updatePeerEurekaNodes方法入參為resolvePeerUrls,解析伙伴的URL。其中isThisMyUrl會比較URL的host與本機host相比較,如果相同就會去除掉。

image


5. 繼續研究下去發現了InstanceInfo、EurekaInstanceConfigBean、InetUtils、findFirstNonLoopbackHostInfo, 大概明白了主要是k8s環境中eureka的網卡信息上查找到的主機名 和 yml中`eureka.instance.hostname` 天然不一樣,所以就導致了DS出現多個結果。 這點在k8s POD中通過 ip addr得到了證實,涉及敏感數據、IP就不貼圖了。

image

總結:

小白嘗試着查看了代碼,分析得到了本地啟動的多個eureka中DS不同的原因; 原因是:K8S中eureka是通過statefulset方式部署的,service-url也是用StatefulSet寫法寫的,POD的環境天生和本地不一樣,也算有點收獲吧,再深入的話得不償失了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM