《Spring Cloud Eureka 高可用集群實戰:從零構建高可靠性的微服務注冊中心》

從零構建高可用 Eureka 集群 | Spring Cloud 微服務架構深度實踐指南

本文核心內容基于《Spring Cloud 微服務架構開發》第1版整理,結合生產級實踐經驗優化
實驗環境:IntelliJ IDEA 2024 | JDK 1.8| Spring Boot 2.1.7.RELEASE | Spring Cloud Greenwich.SR2

項目源碼:本文完整示例代碼已開源至 GitHub,建議結合實踐閱讀
🔗 https://github.com/hongmengchen/spring-cloud-eureka-ha-demo


前言:為什么需要高可用Eureka集群?

在微服務架構中,注冊中心是服務發現與治理的核心樞紐。單節點Eureka Server存在單點故障風險,一旦宕機將導致整個系統服務發現失效。高可用集群通過多節點互備,實現服務注冊表同步與故障自動轉移,保障系統99.99%的可用性

本文是《從零到一!Spring Cloud Eureka 微服務注冊中心手把手搭建指南》的進階篇,將帶領讀者完成以下目標:

  1. 集群架構設計:基于CAP理論(一致性、可用性、分區容錯性)選擇AP模式,確保網絡波動時仍可提供服務發現。
  2. 實戰搭建:通過雙節點互注冊實現數據同步,結合Hosts配置模擬多服務器環境。
  3. 全鏈路改造:覆蓋服務提供者、消費者的集群適配,并驗證故障切換能力。

實施路線圖

基本流程:

  1. 系統環境準備(Hosts配置)
  2. Eureka Server 雙節點改造
  3. 服務提供者集群適配
  4. 改造服務消費者
  5. 測試運行

1. 系統環境準備(Hosts配置)

作用:通過域名映射實現本地多節點模擬

以 Windows 系統為例,如果要構建集群,需要修改 hosts 文件,為其添加主機名的映射。

Windows系統操作指南

  1. 以管理員身份運行記事本
  2. 打開 C:\Windows\System32\drivers\etc\hosts
  3. 添加以下映射規則:
# Eureka 集群節點映射
127.0.0.1 server1  # 主節點域名
127.0.0.1 server2  # 備用節點域名

image-20250327172416199

image-20250327172958058

在修改 hosts 文件時,部分同學可能會遇到無法修改的問題,我另寫了一篇博客以解決大家的問題:Windows 系統 hosts 文件無法保存?三步搞定權限設置!

建議:大家在修改 hosts 文件權限之后,建議使用完再改會來,也是為了安全考慮嗷

關鍵驗證命令

ping server1  # 應返回127.0.0.1
ping server2  # 應返回127.0.0.1

2. Eureka Server 雙節點改造

核心邏輯:節點間互相注冊形成環形依賴

按照搭建 eureka-server 的方式,再搭建一個名為 eureka-server-another 的 Eureka Server。

eureka-server-another 的 application.yml 配置文件內容如下:

節點2配置(server2:7009)

server:port: 7009
spring:application:name: eurake-server-another
eureka:client:fetch-registry: falseregister-with-eureka: falseservice-url:defaultZone: http://server1:7000/eureka/  # 指向節點1instance:hostname: server2 # 必須與Hosts配置一致

創建項目每次都差不多

image-20250327174004712

接下來就是補齊這個初創項目的框架

  1. 補充 pom.xml
  2. 添加目錄結構
  3. 完善配置文件 application.yml
  4. 寫上啟動類
  1. eureka-server-another 和 eureka-server 一樣都是 Eureka Server,因此 pom.xml 文件內容也是一樣的,大家復制粘貼過來就行,記得點擊更新

image-20250327174712214

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><!-- 父項目 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.7.RELEASE</version><relativePath/></parent><!-- 基本信息 --><groupId>cn.hmck</groupId><artifactId>eureka-server-another</artifactId><version>1.0-SNAPSHOT</version><!-- 屬性 --><properties><!-- jdk版本 --><java.version>1.8</java.version><!-- spring-cloud版本 --><spring-cloud.version>Greenwich.SR2</spring-cloud.version><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><!-- 依賴 --><dependencies><!-- spring-boot-starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- spring-boot-starter-test --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!-- spring-cloud-starter-netflix-eureka-server --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency></dependencies><!-- spring-cloud依賴管理 --><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></project>
  1. 添加目錄結構和之前也是一樣的

PixPin_2025-03-27_17-49-22

  1. 接著就是補充 application.yml 配置文件

image-20250327175308942

  1. 最后就是寫上啟動類 EurekaServerApplication.java

新項目的啟動類命名與之前一樣或者不一樣都可以

注意:啟動類外層必須加上一個包名,否則會報錯無法運行,這也是 Spring Cloud 默認規則

image-20250327180043288

這部分代碼和之前依然沒什么區別,可以直接復制粘貼

package cn.hmck.eurekaserveranother;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {public static void main(String[] args) {SpringApplication.run(EurekaServerApplication.class, args);}}

修改項目 eureka-server 的全局配置文件 application.yml。

注意哦!這里是指修改一開始的 eureka-server 項目

eureka-server 的 application.yml 配置文件內容如下:

節點1配置(server1:7000)

server:port: 7000
spring:application:name: eurake-server
eureka:client:fetch-registry: falseregister-with-eureka: falseservice-url:defaultZone: http://server2:7009/eureka/  # 指向節點2instance:hostname: server1 # 必須與Hosts配置一致

關鍵配置解析

  • fetch-registry: false:Server節點不獲取注冊表(僅Client需要)
  • register-with-eureka: false:Server節點不自我注冊
  • 必須保證:集群節點使用相同的spring.application.name

image-20250327181051949


簡單解釋一下

image-20250327181523737


3. 服務提供者集群適配

目標:實現服務多實例注冊與負載均衡

按照搭建 eureka-provider 的方式,搭建一個名為 eureka-provider-another 的服務提供者。

eureka-provider-another 的 application.yml 配置文件內容如下:

server:port: 7007
spring:application:name: eureka-provider
eureka:client:service-url:defaultZone: http://localhost:7000/eureka/instance:hostname: localhost

為了體現集群,所以我們還需要再搭建一個服務提供者 eureka-provider-another,流程和前面搭建第二個服務器是一樣的。并且主要代碼和原來的服務提供者 eureka-provider 是一樣的。

  1. 創建項目 eureka-provider-another
  2. 補充目錄結構、配置文件及啟動類
  1. 創建項目 eureka-provider-another

image-20250327182153708

  1. 補充目錄結構、配置文件及啟動類

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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><!-- 父項目 --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.7.RELEASE</version><relativePath/></parent><!-- 基本信息 --><groupId>cn.hmck</groupId><artifactId>eureka-provider-another</artifactId><version>1.0-SNAPSHOT</version><!-- 屬性 --><properties><!-- jdk版本 --><java.version>1.8</java.version><!-- spring-cloud版本 --><spring-cloud.version>Greenwich.SR2</spring-cloud.version><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><!-- 依賴 --><dependencies><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><version>2.1.7.RELEASE</version><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.1.7.RELEASE</version></dependency></dependencies><!-- spring-cloud依賴管理 --><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>
</project>

啟動類 EurekaProviderApplication.java 代碼

package cn.hmck.eurekaprovider;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication
@EnableEurekaClient
public class EurekaProviderApplication {public static void main(String[] args) {SpringApplication.run(EurekaProviderApplication.class, args);}
}

最終結果展示

image-20250327182746644


4. 改造服務消費者

核心能力:自動故障轉移與請求重試

修改項目 eureka-consumer 中的全局配置文件 application.yml。

作為消費者的 eureka-consumer ,我們并沒有添加其他的,也沒有對其進行修改,代碼未作變動。

eureka-consumer 的 application.yml 配置文件內容如下:

server:port: 7002  
spring:application:  name: eureka-consumer	
eureka:client:service-url:defaultZone: http://localhost:7000/eurekainstance:hostname: localhost

5. 啟動測試

依次啟動兩個 Eureka Server、兩個服務提供者、一個服務消費者。啟動成功后,無論訪問哪個 Eureka Server,Eureka Server 的注冊實例都是一樣的,訪問 server1:7000 的頁面效果如下圖所示。

image-20250327183514510

訪問server2:7009的頁面效果如下圖所示。

image-20250327183538745


Eureka 的常用配置

1. 心跳機制

Eureka 的心跳機制用于客戶端(服務提供者)與 Eureka Server 之間的健康狀態維護。通過心跳,客戶端定期向 Server 發送信號以表明自身存活狀態,避免被 Server 自動剔除。

核心配置參數

在服務提供者的 application.yml 中配置以下參數:

eureka:instance:# 心跳間隔時間(默認30秒)lease-renewal-interval-in-seconds: 30# 心跳超時時間(默認90秒)lease-expiration-duration-in-seconds: 90
  • lease-renewal-interval-in-seconds:客戶端每隔多少秒向 Eureka Server 發送一次心跳。
  • lease-expiration-duration-in-seconds:如果 Server 在此時間內未收到心跳,則認為實例不可用并剔除注冊信息。

工作原理

  1. 客戶端啟動后向 Server 注冊,并開始周期性發送心跳。
  2. Server 接收到心跳后會重置該實例的租約時間。
  3. 若 Server 在 lease-expiration-duration-in-seconds 內未收到心跳,則標記實例為 DOWN 并從注冊表中移除。

2. 自我保護機制

Eureka Server 的自我保護機制旨在應對網絡分區故障場景。當短時間內丟失大量客戶端心跳時,Server 會進入保護模式,保留現有注冊信息,避免因網絡抖動導致服務被誤刪。

核心配置參數

在 Eureka Server 的 application.yml 中配置以下參數:

eureka:server:# 啟用自我保護機制(默認true)enable-self-preservation: true# 觸發保護模式的閾值(默認0.85,即85%心跳丟失)renewal-percent-threshold: 0.85
  • enable-self-preservation:是否啟用自我保護機制,生產環境建議保持 true
  • renewal-percent-threshold:觸發保護模式的心跳丟失比例閾值(例如 0.85 表示 85% 的心跳未更新時觸發)。

工作機制

  1. Server 每分鐘統計心跳續約失敗的比例。
  2. 若失敗比例超過 renewal-percent-threshold,則進入保護模式:
    • 不再剔除任何實例(即使心跳超時)。
    • 在 Eureka 控制臺顯示警告信息:EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP...
  3. 當心跳恢復正常后,Server 會自動退出保護模式。

配置建議

  • 開發環境:可關閉自我保護機制(enable-self-preservation: false),方便快速發現失效實例。
  • 生產環境:務必啟用自我保護機制,避免因網絡波動導致服務列表頻繁變更。
  • 調試技巧:若發現實例未被剔除,需檢查是否因保護模式觸發導致,可通過日志或控制臺提示確認。

特別說明

本次技術實踐文檔的整理與驗證,部分配置優化方案通過 DeepSeek 的智能輔助工具實現效能提升,在此對技術伙伴的支持表示感謝。

技術無界,協作共生
DeepSeek 智能開發平臺


📣 我是鴻·蒙,若有不解之處或發現疏漏,歡迎隨時私信交流!
(雖然不一定秒回,但每條消息都會認真看嗷~ (??????)??)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/76059.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/76059.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/76059.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

實變函數:集合與子集合一例(20250329)

題目 設 r , s , t r, s, t r,s,t 是三個互不相同的數&#xff0c;且 A { r , s , t } A \{r, s, t\} A{r,s,t}, B { r 2 , s 2 , t 2 } B \{r^2, s^2, t^2\} B{r2,s2,t2}, C { r s , s t , r t } C \{rs, st, rt\} C{rs,st,rt} 若 A B C A B C ABC 則 { r , s…

Redis設計與實現-哨兵

哨兵模式 1、啟動并初始化sentinel1.1 初始化服務器1.2 使用Sentinel代碼1.3 初始化sentinel狀態1.4 初始化sentinel狀態的master屬性1.5 創建連向主服務器的網絡連接 2、獲取主服務器信息3、獲取從服務器的信息4、向主從服務器發送信息5、接受主從服務器的頻道信息6、檢測主觀…

藍橋杯省模擬賽 字符串拼接

問題描述 給定四個字符串 a,b,c,d&#xff0c;請將這四個字符串按照任意順序依次連接拼成一個字符串。 請問拼成的字符串字典序最小是多少&#xff1f; 輸入格式 輸入四行&#xff0c;每行包含一個字符串。 輸出格式 輸出一行包含一個字符串&#xff0c;表示答案。 樣例…

【大前端系列20】JavaScript核心:項目實戰從零構建任務管理系統

JavaScript核心&#xff1a;項目實戰從零構建任務管理系統 系列: 「全棧進化&#xff1a;大前端開發完全指南」系列第20篇 核心: 將JavaScript異步編程、事件循環等核心知識應用于實際項目開發 &#x1f4cc; 引言 在前面的文章中&#xff0c;我們深入探討了JavaScript中的異步…

STM32單片機的桌面寵物機器人(基于HAL庫)

效果 基于STM32單片機的桌面寵物機器人 概要 語音模塊&#xff1a;ASR PRO&#xff0c;通過天問block軟件燒錄語音指令 主控芯片&#xff1a;STM32F103C8T6 使用HAL庫 屏幕&#xff1a;0.96寸OLED屏&#xff0c;用來顯示表情 4個舵機&#xff0c;用來當作四只腿 底部一個面…

計算機視覺初步(環境搭建)

1.anaconda 建議安裝在D盤&#xff0c;官網正常安裝即可&#xff0c;一般可以安裝windows版本 安裝成功后&#xff0c;可以在電腦應用里找到&#xff1a; 2.創建虛擬環境 打開anaconda prompt&#xff0c; 可以用conda env list 查看現有的環境&#xff0c;一般打開默認bas…

SQL Server數據庫引擎服務啟動失敗:端口沖突

問題現象&#xff1a; SQL Server 2022 安裝完成后&#xff0c;數據庫引擎服務無法啟動&#xff0c;日志報錯 “TCP 端口 1433 已被占用”&#xff08;ERROR_LOG_SYS_TCP_PORT&#xff09;。 快速診斷 檢測端口占用&#xff1a; # 查看 1433 端口占用情況&#xff08;需管理員權…

全局思維與系統思考

最近接到一些需求&#xff0c;1號位希望每個層級的領導者有眼界&#xff0c;胸懷&#xff0c;格局&#xff0c;全局觀&#xff0c;這些聽起來似乎很抽象&#xff0c;然而它們是每個人、每個團隊成長與成功的核心競爭力。那么&#xff0c;如何才能提升這些能力&#xff1f;就像我…

區間有關的貪心解題記錄435無重疊區間452用最少數量的箭引爆氣球

無重疊區間我的想法是開一個數組a&#xff0c;遍歷給出的區間&#xff0c;在數組a里將對應落在的區間index標記。如果有重復區間就只選擇最小的那個區間標記。但是這道題的區間好像很長-5 * 104 < starti < endi < 5 * 104沒法用數組a表示總的區間范圍。 核心思路是當…

天銳藍盾終端安全防護——企業終端設備安全管控

從辦公室的臺式電腦到員工手中的移動終端&#xff0c;這些設備不僅是工作的得力助手&#xff0c;更是企業數據的重要載體。然而&#xff0c;隨著終端設備的廣泛使用&#xff0c;安全風險也如影隨形。硬件設備使用不當、數據隨意傳輸等問題頻發&#xff0c;使得企業數據面臨著泄…

k8s網絡策略

k8s網絡策略 k8s網絡測試概述查看防火墻策略 k8s網絡策略網絡訪問控制案例&#xff1a;配置k8s網絡策略結果驗證 k8s網絡策略配置示例 k8s網絡測試概述 網絡策略就是設置防火墻 查看防火墻策略 # 獲取當前命名空間下的所有 NetworkPolicy 資源&#xff08;網絡策略&#xff0…

leetcode刷題日記——跳躍游戲 II

[ 題目描述 ]&#xff1a; [ 思路 ]&#xff1a; 題目要求在一個一定能達到數組末尾的跳躍數組中(見55題 跳躍游戲)&#xff0c;找出能夠跳到末尾的最小次數要求次數最少&#xff0c;那肯定是選取能選步數中最大的數。也就是在當前能夠達到的距離中&#xff0c;選擇能夠達到的…

【Java SE】Java比較器:Comparable、Comparator

目錄 1.前言 2.Comaprable接口 2.1 使用細節 2.2 案例演示 3.Comparator接口 3.1 為什么需要Comparator接口 3.2 使用細節 3.3 案例演示 4.Comparable、Comparator對比 1.前言 Java 中的對象&#xff0c;正常情況下&#xff0c;只能進行比較&#xff1a; 或 ! 。不…

(二)創建實例

在這節中&#xff0c; 創建一個實例初始化Vulkan庫,指定驅動程序需要使用的應用程序信息 1&#xff0c;要有個實例句柄 VkInstance instance; 2&#xff0c;設置創建Vulkan驅動程序需要的信息&#xff0c; VkInstanceCreateInfo createInfo {}; createInfo.sType VK_STRUCTUR…

HCIP之VRRP

1. VRRP是什么 VRRP&#xff08;Virtual Router Redundancy Protocol&#xff0c;虛擬路由冗余協議&#xff09;是一種用于提高網絡可靠性的容錯協議。它通過將多臺路由器虛擬成一臺虛擬路由器&#xff0c;實現網關的冗余備份。當主路由器&#xff08;Master&#xff09;出現故…

高效內存管理:x86-64架構中的分頁機制

在 x86-64 架構的世界里&#xff0c;內存分頁機制扮演著舉足輕重的角色&#xff0c;它就像是一座橋梁&#xff0c;連接著虛擬地址與物理地址。簡單來說&#xff0c;內存分頁機制就是將線性地址&#xff08;也就是虛擬地址&#xff09;切分成一個個固定大小的頁&#xff0c;并把…

【軟件工程】填空題

真題 2024-10 16.數據字典是用來定義_____中各個成分的具體含義的。 17.模塊設計的基本原則是_____。 18.接口是操作的一個集合,其中每個操作描述了類、構件或子系統的一個_____。 19.耦合是指不同模塊之間_____的度量。 20.RUP的突出特點是,它是一種以用況為驅動的、…

第二卷:海鹽城血戰(37-72回)正反人物群像

第二卷&#xff1a;海鹽城血戰&#xff08;37-72回&#xff09;正反人物群像 核心矛盾&#xff1a;寒門軍事崛起 → 內部傾軋 → 制度性腐敗 主題&#xff1a;通過人物群像展現寒門勝利的虛幻性與權力異化的必然性 一、正派陣營&#xff08;寒門抗爭勢力&#xff09; 1. 劉裕…

23_js面向對象

上次我們講運動函數&#xff0c;實際開發不會寫運動函數。只是講一下思想。 現在講一下用原生js去實現輪播圖&#xff0c;引入到對象 首先&#xff0c;要明確 面向對象不是語法&#xff0c;是一個思想&#xff0c;是一種編程模式 面向&#xff1a;朝向 面向對象&#xff1a…

torch不能使用cuda的解決方案

遇到了這樣的報錯&#xff0c;說明 torch不能使用cuda 反思 我頻繁地嘗試安裝不同的 nvdia 驅動&#xff0c;浪費了很多時間。因為我的錯誤地認為nvidia會自帶cuda&#xff0c;其實cuda需要單獨安裝。 還有我的torch是cpu版本的&#xff0c;即使nvidia cuda安裝了&#xff0…