微服務(三) Eureka註冊中心和Ribbon負載均衡

iucbjb發表於2021-10-27

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規則的客戶端也會將其忽略。併發連線數的上限,可以由客戶端的..ActiveConnectionsLimit屬性進行配置。
WeightedResponseTimeRule 為每一個伺服器賦予一個權重值。伺服器響應時間越長,這個伺服器的權重就越小。這個規則會隨機選擇伺服器,這個權重值會影響伺服器的選擇。
ZoneAvoidanceRule 以區域可用的伺服器為基礎進行伺服器的選擇。使用Zone對伺服器進行分類,這個Zone可以理解為一個機房、一個機架等。而後再對Zone內的多個服務做輪詢。
BestAvailableRule 忽略那些短路的伺服器,並選擇併發數較低的伺服器。
RandomRule 隨機選擇一個可用的伺服器。
RetryRule 重試機制的選擇邏輯

預設的實現就是ZoneAvoidanceRule,是一種輪詢方案

2.3 自定義負載均衡策略

注意**,一般用預設的負載均衡規則,不做修改。

2.3.飢餓載入

Ribbon預設是採用懶載入,即第一次訪問時才會去建立LoadBalanceClient,請求時間會很長。

而飢餓載入則會在專案啟動時建立,降低第一次訪問的耗時,通過下面配置開啟飢餓載入:

ribbon:
  eager-load:
    enabled: true
    clients: userservice

相關文章