分佈式 springcloud 之 Eureka 集羣

Eureka集羣

當註冊中心扛不住高併發的時候,這時候 要用集羣來扛;
建立3個註冊中心,3個註冊中心中的pom.xml是一樣的我這裏就只粘貼一個了

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.hu</groupId>
        <artifactId>t224springcloud</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>microservice-eureka-server-2001</artifactId>
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--  修改後立即生效,熱部署  -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>springloaded</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

在這裏插入圖片描述

在每個項目的啓動類上加 @EnableEurekaServer 這個註解

package com.hu.microserviceeurekaserver2001;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class MicroserviceEurekaServer2001Application {

    public static void main(String[] args) {
        SpringApplication.run(MicroserviceEurekaServer2001Application.class, args);
    }

}

前面單機的時候 eureka註冊中心實例名稱 是localhost,現在是集羣,不能三個實例都是localhost,這裏複雜的辦法是搞三個虛擬機,麻煩,這裏有簡單辦法,直接配置本機hosts,來實現本機域名映射;
找到 C:\Windows\System32\drivers\etc 打開hosts,加配置
在這裏插入圖片描述
修改三個項目的application.yml文件,主要是修改 hostname和defaultZone
在這裏插入圖片描述
啓動方式:

http://eureka2001.hu.com:2001/
http://eureka2002.hu.com:2002/
http://eureka2003.hu.com:2003/

在這裏插入圖片描述
這個集羣成功

集羣簡化(騷操作)

像上面的那種集羣方式,需要創建多個項目,多個項目的內容都是差不多的。有沒有隻創建一個項目就可以有多個的呢!答案是有的。上面eureka服務搭建,除了yml文件不一樣,其他文件都一樣,那麼我們有什麼辦法能夠將多個eureka服務集合到一個工程中去呢?

各位看官且聽我細說

創建一個一個microservice-eureka-server(三合一)子工程
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.hu</groupId>
        <artifactId>t224springcloud</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>microservice-eureka-server</artifactId>


    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--  修改後立即生效,熱部署  -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>springloaded</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

yml文件(關鍵)
這是利用springboot多配置的特點,在啓動的時候激活指定的配置

---
server:
  port: 2001
  context-path: /
eureka:
  instance:
    hostname: eureka2001.hu.com
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://eureka2002.hu.com:2002/eureka/,http://eureka2003.hu.com:2003/eureka/
spring:
  profiles: eureka2001
---
server:
  port: 2002
  context-path: /
eureka:
  instance:
    hostname: eureka2002.hu.com
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://eureka2001.hu.com:2001/eureka/,http://eureka2003.hu.com:2003/eureka/
spring:
  profiles: eureka2002
---
server:
  port: 2003
  context-path: /
eureka:
  instance:
    hostname: eureka2003.hu.com
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://eureka2001.hu.com:2001/eureka/,http://eureka2002.hu.com:2002/eureka/
spring:
  profiles: eureka2003

idea中配置一下
在這裏插入圖片描述
啓動類上加上 @EnableEurekaServer,啓動方式是跟上面這個相同的。效果也是一樣
在這裏插入圖片描述

Eureka自我保護機制

下面的紅字出現的原因是因爲eureka的自我保護機制,因爲服務沒有被調用的原因,要解決這個問題
在這裏插入圖片描述
默認情況下,當eureka server在一定時間內沒有收到實例的心跳,便會把該實例從註冊表中刪除(默認是90秒),但是,如果短時間內丟失大量的實例心跳,便會觸發eureka server的自我保護機制,比如在開發測試時,需要頻繁地重啓微服務實例,但是我們很少會把eureka server一起重啓(因爲在開發過程中不會修改eureka註冊中心),當一分鐘內收到的心跳數大量減少時,會觸發該保護機制。可以在eureka管理界面看到Renews threshold和Renews(last min),當後者(最後一分鐘收到的心跳數)小於前者(心跳閾值)的時候,觸發保護機制,會出現紅色的警告:

EMERGENCY!EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT.RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEGING EXPIRED JUST TO BE SAFE.

從警告中可以看到,eureka認爲雖然收不到實例的心跳,但它認爲實例還是健康的,eureka會保護這些實例,不會把它們從註冊表中刪掉。

該保護機制的目的是避免網絡連接故障,在發生網絡故障時,微服務和註冊中心之間無法正常通信,但服務本身是健康的,不應該註銷該服務,如果eureka因網絡故障而把微服務誤刪了,那即使網絡恢復了,該微服務也不會重新註冊到eureka server了,因爲只有在微服務啓動的時候纔會發起註冊請求,後面只會發送心跳和服務列表請求,這樣的話,該實例雖然是運行着,但永遠不會被其它服務所感知。所以,eureka server在短時間內丟失過多的客戶端心跳時,會進入自我保護模式,該模式下,eureka會保護註冊表中的信息,不在註銷任何微服務,當網絡故障恢復後,eureka會自動退出保護模式。自我保護模式可以讓集羣更加健壯。

但是我們在開發測試階段,需要頻繁地重啓發布,如果觸發了保護機制,則舊的服務實例沒有被刪除,這時請求有可能跑到舊的實例中,而該實例已經關閉了,這就導致請求錯誤,影響開發測試。所以,在開發測試階段,我們可以把自我保護模式關閉,只需在eureka server配置文件中加上如下配置即可:

eureka.server.enable-self-preservation=false

在此基礎上還可以進一步配置Eureka Server清理無效節點的時間間隔

eureka.server.eviction-interval-timer-in-ms=10000 # 清理間隔(單位毫秒,默認是60*1000)
還可以在Eureka Client端配置開啓健康檢查,並按需配置續約更新時間和到期時間

eureka.client.healthcheck.enabled=true # 開啓健康檢查(需要spring-boot-starter-actuator依賴)
eureka.instance.lease-renewal-interval-in-seconds=30 # 續約更新時間間隔(默認30秒)
eureka.instance.lease-expiration-duration-in-seconds=60 # 續約到期時間(默認90秒)
但在生產環境,不會頻繁重啓,所以,一定要把自我保護機制打開,否則網絡一旦終端,就無法恢復。

一旦進入保護模式,Eureka Server將會嘗試保護其服務註冊表中的信息,不再刪除服務註冊表中的數據(也就是不會註銷任何微服務)。

進入保護模式的條件:
如果Eureka Server最近1分鐘收到renew的次數小於閾值(即預期的最小值,默認爲0.85),則會觸發自我保護模式,此時Eureka Server此時會認爲這是網絡問題,它不會註銷任何過期的實例,即使該實例確實是人爲停掉的。

退出保護模式的條件:
直到最近收到renew的次數大於閾值後,則Eureka Server退出自我保護模式。

自我保護模式閾值計算:
每個instance的預期心跳數目 = 60/每個instance的心跳間隔秒數
閾值 = 所有註冊到服務的instance的數量的預期心跳之和 *自我保護係數(默認爲0.85)
以上的參數都可配置的:

instance的心跳間隔秒數:eureka.instance.lease-renewal-interval-in-seconds
自我保護係數:eureka.server.renewal-percent-threshold

有沒有可能無法退出保護模式呢?比如,原來有兩個實例,後來因爲需要,把一個實例停掉,而且後面也不會再加入其它實例,此時,就無法退出保護模式,被刪掉的實例依然一直存在實例列表中,此時,我們可以手動把該實例從實例列表中刪除,方法如下:

curl -XDELETE http://eureka server地址/eureka/apps/要刪除的服務名/要刪除的實例id(在Eureka Server管理界面可以看到實例的id)
可以用ssh等工具,向Eureka Server發送該請求,Eureka Server收到請求後,會把該實例從列表中刪掉

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章