代碼地址:https://gitlab.com/showkawa/architect/tree/master/microservice/eurake
基於springcloud2分析eurake知識點分三部分:eurake高可用集群搭建, eurake的自我保護機制 ,eurake的原理分析
1.eurake高可用集群搭建
高可用注冊中心
在微服務中,注冊中心非常核心,可以實現服務治理,如果一旦注冊出現故障的時候,可能會導致整個微服務無法訪問,在這時候就需要對注冊中心實現高可用集群模式。
Eureka高可用原理
默認情況下Eureka是服務注冊中心,默認是注冊自己(默認配置register-with-eureka: true)
###因為該應用為注冊中心,不需要注冊自己
register-with-eureka: false
###不需要去注冊中心上檢索服務
fetch-registry: true
Eureka高可用實際上將自己作為服務向其他服務注冊中心注冊自己,這樣就可以形成一組相互注冊的服務注冊中心,從而實現服務清單的互相同步,達到高可用效果。
Eureka集群環境搭建
Eureka 1 配置
###服務端口號
server:
port: 9100
###eureka 基本信息配置
spring:
application:
name: brian-eureka-server
eureka:
instance:
###注冊到eurake ip地址
hostname: 127.0.0.1
client:
serviceUrl:
defaultZone: http://127.0.0.1:9200/eureka/
###集群里面eurake相互注冊
register-with-eureka: true
###集群相互注冊下,需要檢索服務
fetch-registry: true
Eureka 2 配置
###服務端口號 server: port: 9200 ###eureka 基本信息配置 spring: application: name: brian-eureka-server eureka: instance: ###注冊到eurekaip地址 hostname: 127.0.0.1 client: serviceUrl: defaultZone: http://127.0.0.1:9100/eureka/ ###集群里面eurake相互注冊 register-with-eureka: true ###集群相互注冊下,需要檢索服務
fetch-registry: true
客戶端集成Eureka集群配置
server:
port: 8012
###服務別名----服務注冊到注冊中心名稱
spring:
application:
name: brian-member-server
eureka:
client:
service-url:
##### 將會員服務注冊到eureka服務地址
defaultZone: http://localhost:9200/eureka,http://localhost:9100/eureka
### 需要將我的服務注冊到eureka上
register-with-eureka: true
####需要檢索服務
fetch-registry: true
Maven配置
服務端配置
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <!-- 注意: 這里必須要添加, 否者各種依賴有問題 --> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/libs-milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>
客戶端配置
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
測試eurake集群
開啟5個服務,注冊中心2個 EurakeServerApplication 01和02 ,會員member服務2個, 訂單order服務1個
查看注冊中心端口 9100,此時上面只顯示有9200eurake的注冊信息,說明現在該9100端口的注冊中心是備機
查看注冊中心端口 9200,此時上面只顯示有全度啟動的服務的注冊信息
此時使用訂單服務order采用RestTemplate方式調用會員服務member, 可以看到會輪詢調用到兩個會員服務8011和8012端口的服務
現在我們假設注冊中心9200的服務和會員服務8012服務同時不可用
現在發現之前注冊的服務信息從9200的注冊中心轉移到了9100注冊中心上去了
原來的order仍然可用,只是現在的輪詢機制調用的是8011這個端口的會員member服務
所以說eurake在高可用方面還是不錯的,通過簡單的配置就可以實現一個高可用的集群
2.eurake的自我保護機制
Eureka詳解
服務消費者模式
獲取服務
消費者啟動的時候,使用服務別名,會發送一個rest請求到服務注冊中心獲取對應的服務信息,讓后會緩存到本地jvm客戶端中,同時客戶端每隔30秒從服務器上更新一次。
可以通過 registry-fetch-intevall-seconds=30參數進行修以通過eureka.client .registry-fetch-intevall-seconds該參數默認值為30, 單位為秒。
服務下線
在系統運行過程中必然會面臨關閉或重啟服務的某個實例的情況,在服務關閉期有我們自然不希望客戶端會繼續調用關閉了的實例。所以在客戶端程序中,當服務實例過正常的關閉操作時,它會觸發一個服務下線的REST請求給Eureka Server, 告訴服務日中心:“我要下線了”。服務端在接收到請求之后,將該服務狀態置為下線(DOWN),井該下線事件傳播出去。
服務注冊模式
失效剔除
有些時候,我們的服務實例並不一定會正常下線,可能由於內存溢出、網絡故障氣因使得服務不能正常工作,而服務注冊中心並未收到“服務下線”的請求。為了從服務表中將這些無法提供服務的實例剔除,Eureka Server 在啟動的時候會創建一個定時任務默認每隔一一段時間(默認為60秒)將當前清單中超時(默認為90秒)沒有續約的服務除出去
自我保護
當我們在本地調試基於Eureka的程序時,基本上都會碰到這樣-一個問題, 在服務主中心的信息面板中出現類似下面的紅色警告信息( )
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY 'RERENENALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIREDTO BE SAFE.
實際上,該警告就是觸發了Eureka Server的自我保護機制。之前我們介紹過,服務注冊到Eureka Server之后,會維護個心跳連接, 告訴Eureka Server自己還活着。Eureka Server在運行期間,會統計心跳失敗的比例在15分鍾之內是否低於85%如果出現低於的情況單機調試的時候很容易滿足,實際在生產環境上通常是由於網絡不穩定導致,Eureka Server會將當前的實例注冊信息保護起來,讓這些實例不會過期,盡可能保護這些注冊信-息。但是,在這段保護期間內實例若出現問題,那么客戶端很容易拿到實際已經不存服務實例,會出現調用失敗的情況,所以客戶端必須要有容錯機制,比如可以使用請使用重試、斷路器等機制。
由於本地調試很容易觸發注冊中心的保護機制,這會使得注冊中心維護的服務不會特別准確。所以,我們在本地進行開發的時候,可以使用eureka.server.enablp-self-preservation=false參數來關閉保護機制,以確保注冊中心可以將不可用的例正確剔除。
關閉服務保護
Eureka服務器端配置 這里以9100端口的注冊中心為例,添加以下核心配置
server:
# 開發測試時關閉自我保護機制,保證不可用服務及時踢出
enable-self-preservation: false
eviction-interval-timer-in-ms: 2000
注意追加的內容是在根節點eureka下面追加的配置
Eureka客戶端配置 這里以8011端口的會員服務為例,添加以下核心配置
# 心跳檢測檢測與續約時間
# 測試時將值設置設置小些,保證服務關閉后注冊中心能及時踢出服務
instance:
###Eureka客戶端向服務端發送心跳的時間間隔,單位為秒(客戶端告訴服務端自己會按照該規則)
lease-renewal-interval-in-seconds: 1
####Eureka服務端在收到最后一次心跳之后等待的時間上限,單位為秒,超過則剔除(客戶端告訴服務端按照此規則等待自己)
lease-expiration-duration-in-seconds: 2
這里跟上面的配置一樣也是基於eureka作為根節點追加的
此處就不一一截圖了,感興趣的可以自己下載代碼測試
3.eurake的原理分析
1.當啟動eurake客戶端應用,比如上面說到的會員服務member,會把當前服務比如服務地址和端口以別名的注冊到注冊中心
2.當服務消費者比如上面說到的order訂單服務,在接口調用的時候,使用服務別名也就是service id去注冊中心獲取實際的rpc遠程調用地址
3. 服務消費者在獲取到實際的rpc遠程調用地址后,在本地使用HttpClient技術調用遠程接口
流程圖如下: