1. 程式人生 > >微服務Spring Cloud常見問題與總結

微服務Spring Cloud常見問題與總結

Spring Cloud常見問題與總結

Eureka常見問題

1.Eureka註冊服務慢

預設情況下,服務註冊到Eureka Server的過程比較慢。在開發或測試時,常常希望能夠加速這一過程,從而提升工作效率。

Srping Cloud官方文件詳細描述了該問題的原因並提供瞭解決方案。
服務註冊涉及到週期性心跳,預設30秒一次(通過客戶端配置的serviceUrl)。只有當例項、伺服器端和客戶端的本地快取中的元資料都相同時,服務才能被其他客戶端發現(所以可能需要3次心跳)。可以使用引數eureka.instance.leaseRenwalIntervalInSeconds修改時間間隔,從而加快客戶端連線到其他服務的過程。在生產環境中最好堅持使用預設值,因為在伺服器內部有一些計算,他們會對續約做出假設。
綜上,要想解決服務註冊慢的問題,只需將eureka.instance.leaseRenwalIntervalInSeconds設成一個更小的值,該配置用於EurekaClient向Eureka Server傳送心跳的時間間隔,預設是30,單位是秒。在生產環境中,建議堅持使用預設值。

2.已停止的微服務節點登出慢或不登出

在開發環境下,常常希望Eureka Server能迅速有效地登出已停止的微服務例項。然而,
由於Eureka Server清理無效節點週期長(預設90秒),以及自我保護模式等原因,可能
會遇到微服務登出慢甚至不登出的問題。解決方案如下:

 Eureka Server端:
配置關閉自我保護,並按需設定Eureka Server清理無效節點的時間間隔。
eureka.server.enable-self-preservation
#設定為false,關閉自我保護,從而保證會登出微服務
eureka.server.eviction-interval-timer-in-ms
#清理間隔(單位毫秒,預設是60*1000)

Eureka Client端:
配置開啟健康檢查,並按需配置持續更新的時間和到期時間。
eureka.client.healthcheck.enabled
#設為true,開啟健康檢查(需要spring-boot-starter-actuatoryi依賴)
eureka.instance.lease-xepiration-duration-in-seconds
#續約到期時間(預設90秒)

值得注意的是,這些配置僅建議在開發或測試時使用,生產環境建議堅持使用預設值。

3.如何自定義為服務的InstanceID

探討如何自定義微服務的Instance ID。Instance ID用於唯一標識註冊到Eureka Server
上的微服務例項。

在這裡插入圖片描述

在Spring Cloud中,服務Instance ID預設值是spring.cloud.client.hostname:{spring.cloud.client.hostname}:{
spring.cloud.application.name}:KaTeX parse error: Expected '}', got 'EOF' at end of input: …on.instance_id:

{server.port}}。
如果想要自定義這部分的內容,只需在為服務中配置eureka.instance.instance_id屬性即可。

這樣,就可將微服務microservice-provider-user的Instacnce ID設為IP:埠的形式。
這樣設定後效果如下。
在這裡插入圖片描述

4.Eureka的UNKNOWN問題總結與解決

註冊資訊UNKNOWN,是新手常會遇到的情況,一種是應用名稱UNKNOWN,另一種是應用狀態
UNKNOWN。下面分別討論這兩種情況。
在這裡插入圖片描述

應用名稱UNKNOWN
應用名稱UNKNOWN顯然不合適,首先是微服務的名稱不夠語義化,無法直觀看出這是哪個微服務;
更重要的是,我們常常使用應用名稱消費對應微服務的介面。
一般來說有兩種情況會導致該問題的發生:
末配置spring.application.name或者eureka.instance.appname屬性。如果這兩個屬性均
不配置,就會導致應用名稱UNKNOWN的問題。
某些版本SpringFox會導致該問題,例如SpringFox 2.6.0.建議使用SpringFox 2.6.1或更新版本。

微服務例項狀態UNKNOWN
微服務例項狀態UNKNOWN同樣很麻煩。一般來講,只會請求狀態是UP的微服務。該問題一般由健康檢查
所導致。

eureka.client.healthcheck.enabled=true必須設定在application.yml中,而不能設定在
bootstrap.yml中,否則一些場景下會導致應用狀態UNKNOW的問題。

Hystrix/Feign整合Hystrix後首次請求失敗

某些場景下,Feign或Ribbon整合Hystrix後,會出現首次呼叫失敗的問題。
本節將對該問題做一些總結。

1.原因分析

Hystrix預設的超時時間是一秒,如果在1秒內得不到響應,就會進入fallback邏輯。由
於Spring的懶載入機制,首次請求往往會比較慢,因此在某些機器(特別是配置低的機器)
上,首次請求需要的時間可能就會大於1秒。

2.解決方案

有很多方式解決該問題,以下列舉集中比較簡單的方案。
方法一:延長Hystrix的超時時間
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000
該配置讓Hystrix的超時時間改為5秒。
方式二:禁用Hystrix的超時
hystrix.command.default.execution.timeout.enabled: false
方式三:對於Feign,還可為Feign禁用Hystrix
feign.hystrix.enable: false
這樣還可為Feign全域性禁用Hystrix支援。該方式比較極端,一般不建議使用。

Turbine聚合的資料不夠完整

在某些版本的SpringCloud(例如Brixton SR5)中,Turbine會發生該問題。該問題的直觀體現是:
使用Turbine聚合了多個微服務,但在Hystrix Dashboard上只能看到部分微服務的監控資料。
例如Turbine配置如下:
turbine:
appConfig: microservice-consumer-movie,microservice-consumer-movie-feign
-hystrix-fallback-stream
clusterNameExpression: “‘default’”

Turbine理應聚合microservice-consumer-movie和microservice-consumer-movie-
feign-hystrix-fallback-stream這兩個微服務的監控資料,然而開啟Hystrix Dashboard時,
會發現Dashboard上只顯示部分微服務的監控資料。
在這裡插入圖片描述
解決方案
當Turbine聚合的為服務部署在同一臺主機上時,就會出現該問題。
解決方案如下:
方法一:為各個微服務配置不同的hostname,並將preferIpAddress設定為false或者不設定。

方式二:設定turbine,combine-host-port = true。

方式三:升級Spring Cloud到Camden或更新版本。當然,也可單獨升級Spring Cloud Netflix
到1.2.0或更新版本(一般不建議單獨升級Spring Cloud Netflix,因為可能會跟Spring Cloud
其他元件衝突)。
這是因為老版本中的turbine.combine-host-port預設值是false。Spring Cloud已經意識到該
問題,所以在新的版本中將該屬性預設值修改為true。該解決方案和方法二本質上是一致的。

Spring Cloud各元件配置屬性

2.原生配置
Spring Cloud整合了很多類庫,例如Eureka、Ribbon、Feign等。這些元件自身也有一些配置屬性,如下:
在這裡插入圖片描述

Spring Cloud定位問題思路總結。

排查問題的思路不妨按照以下步驟展開。
1.排查配置問題
YAML縮排是否正確
曾有朋友發現Spring Cloud應用程式無法正常啟動。或配置無法正常載入。
最後發現,僅僅是YAML配置檔案縮排不正確。
類似問題應在編碼的過程中嚴格規避。

配置屬性是否正確
配置屬性寫錯是個非常常見的問題。儘管該問題很低階。
很多場景下,這類問題可藉助IDE的提示功能來排查——當IDE不自動提示或
給出警告時,應格外注意。

配置屬性的位置是否正確
想請屬性到底是寫在application.yml還是bootstrap.yml中。

2.排查環境問題
環境變數
例如Java環境變數、Maven環境變數以及Docker容器環境變數等。當應用無法
正常工作時,應該確保環境變數配置正確。

依賴下載是否完整

網路問題
微服務之間通過網路保持通訊,因此,網路常常是排查的關鍵。

3.排查程式碼問題
很多時候常常是少了某個註解,或是依賴缺失,而導致了各種異常。

4.排查Spring Cloud自身問題
如果確定不是程式碼問題,就可Debug一下Spring Cloud的程式碼了。

本文大部分內容轉載自周立的《Spring Cloud與Docker微服務架構實戰》