1. Eureka註冊中心
1.1 Eureka的結構和作用
在上一篇文章中 微服務(二)服務拆分及遠端呼叫
- order-service在發起遠端呼叫的時候,該如何得知user-service例項的ip地址和埠?
- 有多個user-service例項地址,order-service呼叫時該如何選擇?
- order-service如何得知某個user-service例項是否依然健康,是不是已經當機?
這些問題都需要利用SpringCloud中的註冊中心來解決,其中最廣為人知的註冊中心就是Eureka,其結構如下:
問題1:order-service如何得知user-service例項地址?
獲取地址資訊的流程如下:
- user-service服務例項啟動後,將自己的資訊註冊到eureka-server(Eureka服務端)。這個叫服務註冊
- eureka-server儲存服務名稱到服務例項地址列表的對映關係
- order-service根據服務名稱,拉取例項地址列表。這個叫服務發現或服務拉取
問題2:order-service如何從多個user-service例項中選擇具體的例項?
- order-service從例項列表中利用負載均衡演算法選中一個例項地址
- 向該例項地址發起遠端呼叫
問題3:order-service如何得知某個user-service例項是否依然健康,是不是已經當機?
- user-service會每隔一段時間(預設30秒)向eureka-server發起請求,報告自己狀態,稱為心跳
- 當超過一定時間沒有傳送心跳時,eureka-server會認為微服務例項故障,將該例項從服務列表中剔除
- order-service拉取服務時,就能將故障例項排除了
注意:一個微服務,既可以是服務提供者,又可以是服務消費者,因此eureka將服務註冊、服務發現等功能統一封裝到了eureka-client端
接下來的步驟
1.2 搭建eureka-server
首先註冊中心服務端:eureka-server,這必須是一個獨立的微服務
1.2.1 建立eureka-server子模組
1.2.2 pom檔案
引入SpringCloud為eureka提供的starter依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
1.2.3 建立主啟動類
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
1.2.4 yml檔案
server:
port: 8090
spring:
application:
name: eurekaServer
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8090/eureka
1.2.5 啟動服務
啟動服務然後訪問http://127.0.0.1:8090
1.3 服務註冊
在user-service中引入
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
user-service中,修改application.yml檔案,新增服務名稱、eureka地址:
spring:
application:
name: userservice
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8090/eureka
1.4 啟動多個user-service例項
1.5 服務發現
我們將order-service的邏輯修改:向eureka-server拉取user-service的資訊,實現服務發現。
服務發現也需要知道eureka地址,因此第二步與服務註冊一致,都是配置eureka資訊:
在order-service中,修改application.yml檔案,新增服務名稱、eureka地址:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
spring:
application:
name: orderservice
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8090/eureka
1.6 服務拉取和負載均衡
給RestTemplate這個Bean新增一個@LoadBalanced註解:
用服務名代替ip、埠:
2. Ribbon負載均衡
2.1 負載均衡流程
2.2 負載均衡策略
負載均衡的規則都定義在IRule介面中,而IRule有很多不同的實現類:
內建負載均衡規則類 | 規則描述 |
---|---|
RoundRobinRule | 簡單輪詢服務列表來選擇伺服器。它是Ribbon預設的負載均衡規則。 |
AvailabilityFilteringRule | 對以下兩種伺服器進行忽略: (1)在預設情況下,這臺伺服器如果3次連線失敗,這臺伺服器就會被設定為“短路”狀態。短路狀態將持續30秒,如果再次連線失敗,短路的持續時間就會幾何級地增加。 (2)併發數過高的伺服器。如果一個伺服器的併發連線數過高,配置了AvailabilityFilteringRule規則的客戶端也會將其忽略。併發連線數的上限,可以由客戶端的 |
WeightedResponseTimeRule | 為每一個伺服器賦予一個權重值。伺服器響應時間越長,這個伺服器的權重就越小。這個規則會隨機選擇伺服器,這個權重值會影響伺服器的選擇。 |
ZoneAvoidanceRule | 以區域可用的伺服器為基礎進行伺服器的選擇。使用Zone對伺服器進行分類,這個Zone可以理解為一個機房、一個機架等。而後再對Zone內的多個服務做輪詢。 |
BestAvailableRule | 忽略那些短路的伺服器,並選擇併發數較低的伺服器。 |
RandomRule | 隨機選擇一個可用的伺服器。 |
RetryRule | 重試機制的選擇邏輯 |
預設的實現就是ZoneAvoidanceRule,是一種輪詢方案
2.3 自定義負載均衡策略
注意**,一般用預設的負載均衡規則,不做修改。
2.3.飢餓載入
Ribbon預設是採用懶載入,即第一次訪問時才會去建立LoadBalanceClient,請求時間會很長。
而飢餓載入則會在專案啟動時建立,降低第一次訪問的耗時,通過下面配置開啟飢餓載入:
ribbon:
eager-load:
enabled: true
clients: userservice