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