javascript
SpringCloud之Eureka的常见问题及配置优化
SpringCloud之Eureka的常見問題及配置優化
- 1.EurekaServer集群中節點均出現在unavailable-replicas下
- 1.問題描述
- 2.解決方式
- 3.原因
- 2. Eureka的Server端的參數配置優化
- 3.Eureka的Client端的參數配置優化
1.EurekaServer集群中節點均出現在unavailable-replicas下
1.問題描述
我在啟動了3個EurekaServer服務后,在dashboard的General Info中發現,集群中的節點均出現在unavailable-replicas下,沒有出現在available-replicas中,這樣雖然我的集群是可用的,但是總感覺不踏實,最后通過源碼發現,是自己的配置不對。
2.解決方式
那么需要怎么解決呢?通過多次試驗,主要是以下幾個配置:
1.
spring.application.name的值要一樣
基本上就是以上兩三點。
3.原因
我訪問的dashboard的頁面主要是通過EurekaController下的這status的get請求得到的,如下:
@RequestMapping(method = {RequestMethod.GET} ) public String status(HttpServletRequest request, Map<String, Object> model) {this.populateBase(request, model);this.populateApps(model);StatusInfo statusInfo;try {//獲取集群中peer節點的狀態信息statusInfo = (new StatusResource()).getStatusInfo();} catch (Exception var5) {statusInfo = Builder.newBuilder().isHealthy(false).build();}model.put("statusInfo", statusInfo);this.populateInstanceInfo(model, statusInfo);this.filterReplicas(model, statusInfo);return "eureka/status"; }下面我就看下getStatusInfo()這個方法:
@GET public StatusInfo getStatusInfo() {return this.statusUtil.getStatusInfo(); }再往下跟,我們看下statusUtil.getStatusInfo()這個方法:
public StatusInfo getStatusInfo() {Builder builder = Builder.newBuilder();int upReplicasCount = 0;StringBuilder upReplicas = new StringBuilder();StringBuilder downReplicas = new StringBuilder();StringBuilder replicaHostNames = new StringBuilder();Iterator var6 = this.peerEurekaNodes.getPeerEurekaNodes().iterator();while(var6.hasNext()) {PeerEurekaNode node = (PeerEurekaNode)var6.next();if (replicaHostNames.length() > 0) {replicaHostNames.append(", ");}replicaHostNames.append(node.getServiceUrl());//判斷是否能夠加入到available-replicas中if (this.isReplicaAvailable(node.getServiceUrl())) {upReplicas.append(node.getServiceUrl()).append(',');++upReplicasCount;} else {downReplicas.append(node.getServiceUrl()).append(',');}}builder.add("registered-replicas", replicaHostNames.toString());builder.add("available-replicas", upReplicas.toString());builder.add("unavailable-replicas", downReplicas.toString());if (this.peerEurekaNodes.getMinNumberOfAvailablePeers() > -1) {builder.isHealthy(upReplicasCount >= this.peerEurekaNodes.getMinNumberOfAvailablePeers());}builder.withInstanceInfo(this.instanceInfo);return builder.build();}下面我們再往下跟,主要看下isReplicaAvailable(node.getServiceUrl())這個判斷的方法:
private boolean isReplicaAvailable(String url) {try {//從其他節點中獲取當前節點的注冊信息,即當前的服務端要注冊到其他節點,如果沒注冊,這里的app就會返回null//而控制能否注冊的參數就是eureka.client.register-with-eureka//然后就是還要能夠拉取,如果不能及時拉取,就只能等其它節點向我同步了,會產生延遲或者數據不同步(一致)//除此之外,還要注意一點,就是registry.getApplication(this.myAppName, false);這個方法中myAppName,這就 //說集群中的每個server的名字要一樣,即spring.application.name的值要一樣if (app == null) {Application app = this.registry.getApplication(this.myAppName, false);if (app == null) {return false;}Iterator var3 = app.getInstances().iterator();//循環判斷peerEurekaNodes中的hostname是否與注冊到我這個服務的節點的hostname一致while(var3.hasNext()) {InstanceInfo info = (InstanceInfo)var3.next();//這個函數比較重要,就是判斷hostname是否一致,下面我們看下if (this.peerEurekaNodes.isInstanceURL(url, info)) {return true;}}} catch (Throwable var5) {logger.error("Could not determine if the replica is available ", var5);}return false;}下面我們看下isInstanceURL()這個方法:
public boolean isInstanceURL(String url, InstanceInfo instance) {String hostName = hostFromUrl(url);String myInfoComparator = instance.getHostName();if (this.clientConfig.getTransportConfig().applicationsResolverUseIp()) {myInfoComparator = instance.getIPAddr();}return hostName != null && hostName.equals(myInfoComparator); }其實這個方法很簡答, 就是從url中抽取hostname與注冊進來的節點的hostname盡心比較。
2. Eureka的Server端的參數配置優化
eureka:client:# 開啟注冊表的拉取fetch-registry: trueregister-with-eureka: trueservice-url:defaultZone: http://eureka-8700:8700/eureka/,http://eureka-8701:8700/eureka/,http://eureka-8702:8702/eureka/server:# 自我保護,看服務的多少,如果服務很多,就開啟,服務較少,就關閉enable-self-preservation: false# 自我保護的閾值renewal-percent-threshold: 0.85# 剔除服務的間隔時間eviction-interval-timer-in-ms: 1000# 關閉從readOnly讀注冊表use-read-only-response-cache: false# readwrite與readOnly同步的時間間隔response-cache-update-interval-ms: 1000# 從其他peer拉取注冊表重試的次數(最多拉取的次數)registry-sync-retries: 2這樣做的目的主要有兩個:
1.減少服務上下線的延遲;
2.自我保護的開啟或者關閉,需要看網絡和服務的多少
3.服務更新的時候,要先停止服務,再發送下線請求。因為如果先發送下線請求,再停止服務的話,由于服務有續約的定時任務,會導致下線之后,服務又自動續約了,那就只等到server來進行剔除服務了。這里的服務指的是注冊到EurekaServer中的服務。
3.Eureka的Client端的參數配置優化
eureka:client:service-url:defaultZone: http://localhost:8700/eureka,http://localhost:8701/eureka,http://localhost:8702/eureka,prefer-same-zone-eureka:## 開啟注冊表的拉取fetch-registry: true## 說明自己是一個客戶端enabled: true## 拉取注冊表的時間間隔registry-fetch-interval-seconds: 5## 開啟想eurekaServer注冊register-with-eureka: trueinstance:## 續約的時間間隔lease-renewal-interval-in-seconds: 10## 缺少心跳的過期時間lease-expiration-duration-in-seconds: 10除此之外,還有一個小技巧,我們在生產中配置eureka.client.service-url.defaultZone的時候,各個client端的配置盡量要隨機一下,即打亂一下defaultZone中url的順序,這是因為在拉取注冊表的時候,默認從第一個url開始拉取,拉取不到才從下一個拉取,并且最多只能拉取3個;同時,在注冊的時候,只會注冊到第一個url,不會注冊到下面的url。所以我們打亂了順序以后,就減少了對某一個server的依賴,也降低了對某一個server的請求次數。
總結
以上是生活随笔為你收集整理的SpringCloud之Eureka的常见问题及配置优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: x 天后的日期
- 下一篇: JAVA初中级面试题总纲(含答案)