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.rhkb.cn/news/35059.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务存在的问题及解决方案

微服务存在的问题及解决方案 1. 存在问题 1.1 接口拖慢 因为一个接口在并发时&#xff0c;正好执行时长又比较长&#xff0c;那么当前这个接口占用过多的 Tomcat 连接&#xff0c;导致其他接口无法即时获取到 Tomcat 连接来完成请求&#xff0c;导致接口拖慢&#xff0c;甚至…

centos 安装pip时报错 Cannot find a valid baseurl for repo: centos-sclo-rh/x86_64

centos 安装pip时报错 [rootindex-es app-ai]# yum update Loaded plugins: fastestmirror Repository centos-sclo-rh is listed more than once in the configuration Determining fastest mirrors Could not retrieve mirrorlist http://mirrorlist.centos.org?archx86_64…

解决图片转 ICO 图标难题,支持批量处理

还在为图片转 ICO 图标发愁吗&#xff1f;别担心&#xff0c;今天为大家带来一款超实用的工具 ——Any to Icon。它功能强大&#xff0c;可实现批量图片转 ICO 图标&#xff0c;轻松解决格式转换难题。更棒的是&#xff0c;这款工具极为小巧&#xff0c;无需安装&#xff0c;即…

MultiPost--多平台博客发布工具

网站介绍 一键发布内容到多个社交平台的浏览器插件&#xff0c;支持知乎、微博、小红书、抖音等主流平台&#xff0c;支持文字、图片、视频等内容形式. 地址 GitHub &#xff1a; https://github.com/leaper-one/MultiPost-Extension Chorme: https://chromewebstore.google.…

Linux进程状态详解:僵尸进程与孤儿进程的深度探索与实践

文章目录 前言一、进程状态概述1.1 运行状态1.2 阻塞状态1.3 挂起状态 二、具体的Linux操作系统中的进程状态2.1 Linux内核源代码2.2 查看进程状态2.3 D磁盘休眠状态(Disk sleep)D状态的定义&#xff1a; 2.4 T停止状态(stopped)停止状态的概述&#xff1a;停止状态的触发条件&…

【Linux】深入理解进程和文件及内存管理

个人主页~ 深入理解进程和文件及内存管理 一、重谈Linux下一切皆文件二、操作系统对物理内存的管理1、物理内存与磁盘的数据交互2、操作系统对物理内存的管理 三、文件页缓冲区向文件写入数据的过程 四、动态库是如何被加载的关于动态库中的全局变量 五、深入理解地址1、程序地…

★9.4.2 context2D 绘图

返回目录&#xff1a; Qt QML专栏目录结构_qml 项目 目录-CSDN博客 ★9.4.2 context2D 绘图 Object <- context 属性 canvas : QtQuick::Canvas fillRule : enumeration fillStyle : variant fillStyle: 设置或获取当前填充颜色或样式。 font : string g…

汇编基础知识

CPU&#xff1a;一种可以执行机器指令进行运算的芯片&#xff08;微处理器&#xff09;。 存储器&#xff08;内存&#xff09;&#xff1a;存放CPU可以工作的指令和数据&#xff08;指令和数据都是二进制信息&#xff09;。 磁盘不同于内存&#xff0c;磁盘中的数据要读到内…

1536数字三角形

1536数字三角形 ⭐️难度&#xff1a;中等 &#x1f31f;考点&#xff1a;动态规划 &#x1f4d6; &#x1f4da; import java.util.Arrays; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner;public class Main {public static void main(…

基于VMware的虚拟机集群搭建

本文作者&#xff1a; slience_me 文章目录 基于VMware的虚拟机集群搭建1. 安装Vmware2. 构建虚拟机3. 安装Linux4. 网络配置5. 开始克隆6. 初始化系统6.1 开放root账户6.2 SSH服务6.3 设置静态IP6.4 镜像源 host 主机名 基于VMware的虚拟机集群搭建 该集群采用镜像ubuntu-20.0…

windows平台搭建python环境

python语言 Python 是一种高级、解释型、跨平台的编程语言&#xff0c;由Guido van Rossum于1991年设计&#xff0c;并发展成为全球最受欢迎的编程语言之一。它以简单易读的语法、灵活的特性和丰富的标准库闻名&#xff0c;适合初学者和经验丰富的开发者。 Python 支持多种编…

【系统架构设计师】操作系统 - 文件管理 ② ( 位示图 | 空闲区域 管理 | 位号 | 字号 )

文章目录 一、空闲区域 管理1、空闲区域分配2、空闲区域 管理方式 简介 二、位示图 简介1、位示图 表示2、位示图 字号3、位示图 位号4、位示图 中 比特位 分组管理 三、位示图 考点1、计算磁盘 位示图 的大小2、位示图 位置计算 一、空闲区域 管理 1、空闲区域分配 在 索引文件…

SpringData Redis:RedisTemplate配置与数据操作

文章目录 引言一、Redis概述与环境准备二、RedisTemplate基础配置三、连接属性配置四、操作String类型数据五、操作Hash类型数据六、操作List类型数据七、操作Set类型数据八、操作ZSet类型数据九、事务与管道操作总结 引言 Redis作为高性能的NoSQL数据库&#xff0c;在分布式系…

串口烧录出现频繁回复乱码 频繁回复一个数字且烧录失败 字节混乱

这是因为你的芯片没有处于系统存储区启动一直未进入bootloader 解决办法是检查boot引脚接正确没&#xff0c;要在系统存储器启动

共享经济再中介化进程中的技术创新与模式重构研究——以“开源AI智能名片链动2+1模式S2B2C商城小程序“为例

摘要 本文基于共享经济中介化演进的双重逻辑&#xff0c;通过案例研究与技术解构&#xff0c;探讨"开源AI智能名片链动21分销机制S2B2C商城小程序"集成系统如何重构数字经济时代的价值网络。研究发现&#xff0c;该技术生态通过三维需求匹配、动态价值分配与智能风险…

【linux】虚拟机执行sudo yum isntall perl报错 could not retrieve mirrorlist htt:

项目场景&#xff1a; 提示&#xff1a;虚拟机安装拓展包&#xff0c;sudo yum install perl Virtualbox 在不安装增强功能扩展的情况下, 无法自适应分辨率和共享剪切板等操作 问题描述 原因分析&#xff1a; 提示&#xff1a;这里填写问题的分析&#xff1a; 出现这个错误是因…

网络编程知识预备阶段

1. OSI七层模型 OSI&#xff08;Open System Interconnect&#xff09;七层模型是一种将计算机网络通信协议划分为七个不同层次的标准化框架。每一层都负责不同的功能&#xff0c;从物理连接到应用程序的处理。这种模型有助于不同的系统之间进行通信时&#xff0c;更好地理解和…

我的Gitee

算法与数据结构: 浙海大小趴菜的一些记录 后续也会更新一些项目&#xff0c;小趴菜以后也会变得很厉害

Collection合集(单列集合)

Collection代表单列集合&#xff0c;每个元素&#xff08;数据&#xff09;只包含一个值。Collection实际上是一个泛型接口 Collection集合常用API&#xff1a; 代码实现&#xff1a; Collection集合遍历 遍历方式一&#xff1a;迭代器 迭代器是用来遍历集合的专用方式&#…

旅游类小程序界面设计

产品概述 艾啦游是一款互联网旅游类小程序&#xff0c;致力于国内精品旅游&#xff0c;以及拥有自由行、专属热榜单、出行攻略等诸多功能&#xff0c;汇聚了许多国内的人气景点&#xff0c;与诸多城市的酒店也保持合作&#xff0c;打造一体式旅行服务&#xff0c;更有不断上新…