Spring Cloud 中的服務注冊與發現: Eureka詳解

1. 背景

1.1 問題描述

我們如果通過 RestTamplate 進行遠程調用時,URL 是寫死的,例如:

String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();

當機器更換或者新增機器時,這個 URL 就需要相應地變更。這就意味著要通知所有相關服務去修改,進而導致各個項目的配置文件反復更新,各個項目頻繁部署。這種工作既繁瑣又沒有太多實際價值,卻又不得不做,給開發者帶來極大的困擾。

1.2 解決思路

我們可以從生活場景中獲取靈感。在生活里,我們難免要與各種機構(如醫院、學校、政府部門等)打交道,需要保存它們的電話號碼。若機構更換電話號碼,就需通知所有使用方,但這些機構的使用方群體龐大,根本無法做到一一通知,該怎么辦呢?

通常的做法是,機構電話變更時通知 114。用戶需要聯系機構時,先撥打 114 查詢電話,再聯系相應機構。114 查號臺主要有兩個作用:

  • 號碼注冊:服務方將電話上報給 114。
  • 號碼查詢:使用方通過 114 能查到對應的號碼。

同樣,在微服務開發中,也可采用類似方案。服務啟動或變更時,向注冊中心進行報道,注冊中心記錄應用和 IP 的關系。調用方在調用時,先去注冊中心獲取服務方的 IP,再去服務方進行調用。

1.3 什么是注冊中心

在早期的架構體系中,集群概念尚未普及,機器數量較少,那時直接使用 DNS + Nginx 就能滿足幾乎所有服務的發現需求,相關注冊信息直接配置在 Nginx 中。然而,隨著微服務的興起和流量的急劇增長,機器規模不斷擴大,且機器上下線行為頻繁。此時,依靠運維人員手動維護這些配置信息變得非常麻煩。于是,開發者們期望有一個工具,它能維護一個服務列表,機器上線、宕機等信息都能自動更新到這個服務列表上,客戶端獲取這個列表后可直接進行服務調用,這就是注冊中心。

注冊中心主要有三種角色:

  • 服務提供者(Server):在一次業務中,被其他微服務調用的服務,即提供接口給其他微服務。
  • 服務消費者(Client):在一次業務中,調用其他微服務的服務,即調用其他微服務提供的接口。
  • 服務注冊中心(Registry):用于保存 Server 的注冊信息,當 Server 節點發生變更時,Registry 會同步變更。服務與注冊中心通過一定機制通信,如果注冊中心與某服務長時間無法通信,就會注銷該實例。

它們之間的關系以及工作內容,可以通過兩個概念來描述:

  • 服務注冊:服務提供者在啟動時,向 Registry 注冊自身服務,并向 Registry 定期發送心跳匯報存活狀態。
  • 服務發現:服務消費者從注冊中心查詢服務提供者的地址,并通過該地址調用服務提供者的接口。服務發現的一個重要作用就是為服務消費者提供一個可用的服務列表。

1.4 CAP 理論

談及注冊中心,就無法避開 CAP 理論。CAP 理論是分布式系統設計中最基礎且最為關鍵的理論。

  • 一致性(Consistency):CAP 理論中的一致性指的是強一致性,即所有節點在同一時間具有相同的數據。
  • 可用性(Availability):保證每個請求都有響應(響應結果可能不對)。
  • 分區容錯性(Partition Tolerance):當出現網絡分區后,系統仍然能夠對外提供服務。

舉例來說,一個部門在全國各地都有崗位,總部下發通知,由于通知需開會周知全員,當有客戶咨詢時:

  • 一致性:所有成員對客戶的回應結果都是一致的。
  • 可用性:客戶咨詢時,一定有回應。
  • 分區容錯性:當其中一個成員休假時,這個部門的其他成員也可以對客戶提供咨詢服務。

CAP 理論表明:一個分布式系統不可能同時滿足數據一致性、服務可用性和分區容錯性這三個基本需求,最多只能同時滿足其中的兩個。

在分布式系統中,系統間的網絡無法 100% 保證健康,服務又必須對外提供服務,因此 Partition Tolerance 不可避免。那就只能在 C 和 A 中選擇一個,即 CP 或者 AP 架構。

  • CP 架構:為保證分布式系統對外的數據一致性,選擇不返回任何數據。
  • AP 架構:為保證分布式系統的可用性,節點 2 返回 V0 版本的數據(即使這個數據不正確)。

更多參考:一文看懂|分布式系統之CAP理論-騰訊云開發者社區-騰訊云

1.5 常見的注冊中心

  • Zookeeper:Zookeeper 的官方并未明確表明它是一個注冊中心,但在國內 Java 體系中,大部分集群環境都依賴 Zookeeper 來實現注冊中心的功能。
  • Eureka:Eureka 是 Netflix 開發的基于 REST 的服務發現框架,主要用于服務注冊、管理、負載均衡和服務故障轉移。官方聲明在 Eureka 2.0 版本停止維護,不建議使用。不過,Eureka 是 SpringCloud 服務注冊 / 發現的默認實現,所以目前仍有許多公司在使用。
  • Nacos:Nacos 是 Spring Cloud Alibaba 架構中重要的組件,除具備服務注冊、服務發現功能外,Nacos 還支持配置管理、流量管理、DNS、動態 DNS 等多種特性。

下面通過表格對比一下這三種注冊中心基于 CAP 理論的特點:

注冊中心

CAP 理論

Zookeeper

CP

Eureka

AP

Nacos

CP 或 AP(默認 AP)

在分布式環境中,拿到一個錯誤的數據,往往比無法提供實例信息導致請求失敗要好(例如淘寶 11.11、京東 618 等活動,都遵循 AP 原則)。在我們的課堂中,會為大家介紹 Eureka 和 Nacos 的使用。

2. Eureka 介紹

Eureka 是 Netflix OSS 套件中關于服務注冊和發現的解決方案。Spring Cloud 對 Eureka 進行了集成,并作為優先推薦方案進行宣傳。盡管目前 Eureka 2.0 已停止維護,在新的微服務架構設計中也不再建議使用,但當前仍有大量公司的微服務系統將 Eureka 作為注冊中心。

官方文檔:Home · Netflix/eureka Wiki · GitHub

Eureka 主要分為兩個部分:

  • Eureka Server:作為注冊中心 Server 端,向微服務應用程序提供服務注冊、發現、健康檢查等能力。
  • Eureka Client:服務提供者,服務啟動時,會向 Eureka Server 注冊自己的信息(IP、端口、服務信息等),Eureka Server 會存儲這些信息。

關于 Eureka 的學習,主要涵蓋以下三個部分:

  1. ?搭建 Eureka Server。
  2. 將 order - service、product - service 都注冊到 Eureka。
  3. order - service 遠程調用時,從 Eureka 中獲取 product - service 的服務列表,然后進行交互。?

3. 搭建 Eureka Server

Eureka - server 是一個獨立的微服務。

3.1 創建 Eureka - server 子模塊

此步驟可通過相應的開發工具(如 IDEA)進行操作,創建一個新的 Maven 子模塊,用于搭建 Eureka Server。

3.2 引入 eureka - server 依賴

在創建好的子模塊的 pom.xml 文件中添加如下依賴:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring - cloud - starter - netflix - eureka - server</artifactId></dependency>

3.3 項目構建插件

同樣在 pom.xml 文件中,配置項目構建插件:

3.4 完善啟動類

為項目編寫一個啟動類,并在啟動類上添加 @EnableEurekaServer 注解,開啟 eureka 注冊中心服務。示例代碼如下:

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

3.5 編寫配置文件

在 application.yml 文件中進行如下配置:

server:port: 10010spring:application:name: eureka - servereureka:instance:hostname: localhostclient:fetch - registry: false

# 表示是否從Eureka Server獲取注冊信息,默認為true。因為這是一個單點的Eureka Server,不需要同步其他的Eureka Server節點的數據,這里設置為false

register - with - eureka: false # 表示是否將自己注冊到Eureka Server,默認為true。由于當前應用就是Eureka Server,故而設置為false

service - url:

# 設置與Eureka Server的地址,查詢服務和注冊服務都需要依賴這個地址。

defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

3.6 啟動服務

啟動服務后,訪問注冊中心:http://127.0.0.1:10010/ ,若能看到相應頁面,則表明 eureka - server 已啟動成功。

4. 服務注冊

接下來我們將 product - service 注冊到 eureka - server 中。

4.1 引入 eureka - client 依賴

在 product - service 模塊的 pom.xml 文件中添加如下依賴:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring - cloud - starter - netflix - eureka - client</artifactId></dependency>

4.2 完善配置文件

在 product - service 模塊的 application.yml 文件中添加服務名稱和 eureka 地址:

spring:application:name: product - serviceeureka:client:service - url:defaultZone: http://127.0.0.1:10010/eureka

4.3 啟動服務

啟動 product - service 服務后,刷新注冊中心:http://127.0.0.1:10010/ ,可看到 product - service 已成功注冊到 eureka 上。

5. 服務發現

接下來我們修改 order - service,在遠程調用時,從 eureka - server 拉取 product - service 的服務信息,實現服務發現。

5.1 引入依賴

服務注冊和服務發現都封裝在 eureka - client 依賴中,所以服務發現時,同樣引入 eureka - client 依賴:

 

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring - cloud - starter - netflix - eureka - client</artifactId>

</dependency>

5.2 完善配置文件

服務發現也需要知道 eureka 地址,因此配置內容與服務注冊一致,都是配置 eureka 信息:

 

spring:

application:

name: order - service

eureka:

client:

service - url:

defaultZone: http://127.0.0.1:10010/eureka

5.3 遠程調用

在遠程調用時,我們需要從 eureka - server 中獲取 product - service 的列表(可能存在多個服務),并選擇其中一個進行調用。示例代碼如下:

 
import com.bite.order.mapper.OrderMapper;import com.bite.order.model.OrderInfo;import com.bite.order.model.ProductInfo;import org.springframework.cloud.client.ServiceInstance;import org.springframework.cloud.client.discovery.DiscoveryClient;import jakarta.annotation.Resource;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cloud.netflix.eureka.EurekaServiceInstance;import org.springframework.stereotype.Service;import org.springframework.web.client.RestTemplate;import java.util.List;import org.slf4j.Logger;import org.slf4j.LoggerFactory;@Servicepublic class OrderService {private static final Logger log = LoggerFactory.getLogger(OrderService.class);@Autowiredprivate OrderMapper orderMapper;@Resourceprivate DiscoveryClient discoveryClient;@Autowiredprivate RestTemplate restTemplate;public OrderInfo selectOrderById(Integer orderId) {OrderInfo orderInfo = orderMapper.selectOrderById(orderId);//String url = "http://127.0.0.1:9090/product/" + orderInfo.getProductId();//根據應用名稱獲取服務列表List<ServiceInstance> instances = discoveryClient.getInstances("product - service");//服務可能有多個,獲取第一個EurekaServiceInstance instance = (EurekaServiceInstance) instances.get(0);log.info(instance.getInstanceId());//拼接urlString url = instance.getUri() + "/product/" + orderInfo.getProductId();ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}}

5.4 啟動服務

啟動 order - service 服務后,刷新注冊中心:http://127.0.0.1:10010/ ,可看到 order - service 已注冊到 eureka 上。訪問接口:http://127.0.0.1:8080/order/1 ,可以發現遠程調用也成功了。

6. Eureka 和 Zookeeper 區別

Eureka 和 Zookeeper 都是用于服務注冊和發現的工具,它們的區別如下:

對比項

Eureka

Zookeeper

開源項目所屬

Netflix 開源的項目

Apache 開源的項目

遵循原則

基于 AP 原則,保證高可用

基于 CP 原則,保證數據一致性

節點關系

每個節點都是均等的

節點區分 Leader 和 Follower 或 Observer

選舉機制

無選舉機制

如果 Zookeeper 的 Leader 發生故障時,需要重新選舉,選舉過程集群會有短暫時間的不可用

通過以上對 Eureka 的詳細介紹,相信大家對服務注冊與發現以及 Eureka 在 Spring Cloud 中的應用有了更深入的理解。在實際項目中,可根據具體需求選擇合適的注冊中心。

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

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

相關文章

網頁制作15-Javascipt時間特效の記錄網頁停留時間

01效果圖&#xff1a; 02運用&#xff1a; window.setTimeout&#xff08;&#xff09;刷新function&#xff08;&#xff09;函數document.forms&#xff08;&#xff09;&#xff1a;表單if條件語句window.alert&#xff08;&#xff09;窗口警示 03、操作代碼&#xff1a;…

【Rust基礎】排序和分組

排序 簡單排序 整數排序 #[test] fn test_sort(){let mut list vec![1, 5, 3, 2, 4];list.sort(); //?assert_eq!(list, vec![1, 2, 3, 4, 5]); }小數排序 #[test] fn test_sort(){let mut list vec![1, 5, 3, 2, 4];//? 不能直接使用sort&#xff0c;因為f32和f64未實現O…

C++ std::list超詳細指南:基礎實踐(手搓list)

目錄 一.核心特性 1.雙向循環鏈表結構 2.頭文件&#xff1a;#include 3.時間復雜度 4.內存特性 二.構造函數 三.list iterator的使用 1.學習list iterator之前我們要知道iterator的區分 ?編輯 2.begin()end() 3.rbegin()rend() 四.list關鍵接口 1.empty() 2. size…

996引擎 - 紅點系統

996引擎 - 紅點系統 總結NPC 紅點(TXT紅點)Lua 紅點1. Red_Point.lua2. UI_Ex.lua參考資料以下內容是在三端 lua 環境下測試的 總結 紅點系統分幾個部分組成。 M2中設置變量推送。 配置紅點表。 Envir\Data\cfg_redpoint.xls 2.1. UI元素中找到ID填寫 ids 列。 主界面掛載…

C語言——變量與常量

C語言中的變量與常量&#xff1a;簡潔易懂的指南 在C語言編程中&#xff0c;變量和常量是最基本的概念之一。理解它們的區別和使用方法對于編寫高效、可維護的代碼至關重要。本文將詳細介紹C語言中的變量和常量&#xff0c;并通過圖表和代碼示例幫助你更好地理解。 目錄 什么…

PySide(PyQt),使用types.MethodType動態定義事件

以PySide(PyQt)的圖片項為例&#xff0c;比如一個視窗的場景底圖是一個QGraphicsPixmapItem&#xff0c;需要修改它的鼠標滾輪事件&#xff0c;以實現鼠標滾輪縮放顯示的功能。為了達到這個目的&#xff0c;可以重新定義一個QGraphicsPixmapItem類&#xff0c;并重寫它的wheelE…

K8S學習之基礎三十一:k8s中RBAC 的核心概念

Kubernetes (k8s) 中的 RBAC&#xff08;Role-Based Access Control&#xff0c;基于角色的訪問控制&#xff09;是一種用于管理用戶和服務賬戶對集群資源訪問權限的機制。RBAC 允許管理員通過定義角色&#xff08;Role&#xff09;和角色綁定&#xff08;RoleBinding&#xff…

【eNSP實戰】三層交換機使用ACL實現網絡安全

拓圖 要求&#xff1a; vlan1可以訪問Internetvlan2和vlan3不能訪問Internet和vlan1vlan2和vlan3之間可以互相訪問PC配置如圖所示&#xff0c;這里不展示 LSW1接口vlan配置 vlan batch 10 20 30 # interface Vlanif1ip address 192.168.40.2 255.255.255.0 # interface Vla…

軟考系統架構師 — 1 考點分析

目錄 1 考點總結 1 考點總結 章節 內容 真題考察 緒論 1. 緒論 不考 計算機相關知識 2. 計算機系統基礎知識&#xff0c;新增計算機硬件、嵌入式、計算機語言、系統工程 對應計算機組成結構、操作系統、數據庫、計算機網絡、多媒體等知識點&#xff0c;整體分值在 10 …

在Eclipse 中使用 MyBatis 進行開發,通常需要以下步驟:

在Eclipse 中使用 MyBatis 進行開發&#xff0c;通常需要以下步驟&#xff1a; 1. 創建 Maven 項目 首先&#xff0c;在 Eclipse 中創建一個 Maven 項目。如果你還沒有安裝 Maven 插件&#xff0c;可以通過 Eclipse Marketplace 安裝 Maven 插件。 打開 Eclipse&#xff0c;選…

錯誤記錄: git 無法連接到github

錯誤記錄: git 無法連接到github 今天, 新建了一個github倉庫, 但從本地怎么都push不上去.并報錯 gitgithub.com: Permission denied (publickey). fatal: Could not read from remote repository.Please make sure you have the correct access rights and the repository e…

k8s 配置兩個deployment主機級別互斥部署

在 Kubernetes 中&#xff0c;要實現兩個 Deployment 的 Pod 在主機級別互斥部署&#xff0c;可以使用 podAntiAffinity 配置。通過設置 podAntiAffinity&#xff0c;可以確保兩個 Deployment 的 Pod 不會被調度到同一節點上。 實現步驟 定義 Deployment&#xff1a; 為每個…

Unity中WolrdSpace下的UI展示在上層

一、問題描述 Unity 中 Canvas使用World Space布局的UI&#xff0c;想讓它不被3d物體遮擋&#xff0c;始終顯示在上層。 二、解決方案 使用shader解決 在 UI 的材質中禁用深度測試&#xff08;ZTest&#xff09;&#xff0c;強制 UI 始終渲染在最上層。 Shader "Custo…

五子棋小游戲-簡單開發版

一、需求分析 開發一個基于 Pygame 庫的五子棋小游戲&#xff0c;允許兩名玩家在棋盤上輪流落子&#xff0c;當有一方達成五子連珠時游戲結束&#xff0c;顯示獲勝信息&#xff0c;并提供退出游戲和重新開始游戲的操作選項。 1.棋盤顯示 &#xff1a; 顯示一個 15x15 的五子棋…

基于C#的以太網通訊實現:TcpClient異步通訊詳解

基于C#的以太網通訊實現&#xff1a;TcpClient異步通訊詳解 在現代工業控制和物聯網應用中&#xff0c;以太網通訊是一種常見的數據傳輸方式。本文將介紹如何使用C#實現基于TCP協議的以太網通訊&#xff0c;并通過異步編程提高通訊效率。我們將使用TcpClient類來實現客戶端與服…

小秋的矩陣

0小秋的矩陣 - 藍橋云課 問題描述 給你一個 n 行 m 列只包含 0 和 1 的矩陣&#xff0c;求它的所有子矩陣中&#xff0c;是方陣而且恰好包含 k 個 0 的數量。 方陣是行數和列數相等的矩陣。 子矩陣是從一個矩陣當中選取某些行和某些列交叉位置所組成的新矩陣&#xff08;保…

晶晨S905L3芯片_原機安卓4升級安卓9.0_通刷線刷固件包

晶晨S905L3芯片_原機安卓4升級安卓9.0_通刷線刷固件包 線刷方法&#xff1a;&#xff08;新手參考借鑒一下&#xff09; 1、準備好一根雙公頭USB線刷刷機線&#xff0c;長度30-50CM長度最佳&#xff0c;同時準備一臺電腦&#xff1b; 2、電腦上安裝好刷機工具Amlogic USB Bu…

麒麟服務器操作系統Redis部署手冊

軟件簡介 Redis****介紹 REmote DIctionary Server(Redis) 是一個由 Salvatore Sanfilippo 寫的 key-value 存儲系統,是跨平臺的非關系型數據庫。 Redis 是一個開源的使用 ANSI C 語言編寫、遵守 BSD 協議、支持網絡、可基于內存、分布式、可選持久性的鍵值對(Key-Value)存…

(分塊)洛谷 P2801 教主的魔法 題解

之前學過 莫隊 算法&#xff0c;其運用了分塊思想&#xff1b;但是我居然是第一次寫純種的分塊題目。 題意 給你一個長度為 n n n 的序列 a a a&#xff08;一開始 ? a i ∈ [ 1 , 1000 ] \forall a_i\in[1,1000] ?ai?∈[1,1000]&#xff09;。要求執行 q q q 次操作&…

谷歌Chrome或微軟Edge瀏覽器修改網頁任意內容

在谷歌或微軟瀏覽器按F12&#xff0c;打開開發者工具&#xff0c;切換到console選項卡&#xff1a; 在下面的輸入行輸入下面的命令回車&#xff1a; document.body.contentEditable"true"效果如下&#xff1a;