Spring Cloud 中的服务注册与发现: Eureka详解

news2025/3/18 10:11:05

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

@SpringBootApplication

public class EurekaServerApplication {

    public static void main(String[] args) {

        SpringApplication.run(EurekaServerApplication.class, args);

    }

}

3.5 编写配置文件

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

server:

    port: 10010

spring:

    application:

        name: eureka - server

eureka:

    instance:

        hostname: localhost

    client:

        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 - service

eureka:

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;

@Service

public class OrderService {

private static final Logger log = LoggerFactory.getLogger(OrderService.class);

    @Autowired

    private OrderMapper orderMapper;

    @Resource
    
    private DiscoveryClient discoveryClient;

    @Autowired

    private 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());

    //拼接url

    String 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.coloradmin.cn/o/2317152.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通过 SVG 使用 AI 生成理想图片:技术实现与实践指南

文章目录 1. SVG 与 AI 的结合&#xff1a;技术价值2. 技术原理&#xff1a;AI 如何生成 SVG&#xff1f;3. 实现步骤&#xff1a;从需求到图形3.1 定义需求3.2 使用 AI 生成 SVG3.3 验证与调整 4. 代码解析&#xff1a;实现科技感的关键4.1 渐变背景4.2 网格线条4.3 发光六边形…

【AI学习从零至壹】Pytorch神经⽹络

Pytorch神经⽹络 神经网络简介神经元激活函数 神经网络神经⽹络的⼯作过程前向传播(forward) 反向传播(backward)训练神经⽹络 Pytorch搭建并训练神经⽹络神经⽹络构建和训练过程数据预处理构建模型优化器&提取训练数据训练样本 神经网络简介 神经元 在深度学习中&#x…

设计模式-对象创建

对象创建 前言1. Factory Method1.1 模式介绍1.2 模式代码1.2.1 问题代码1.2.2 重构代码 1.3 模式类图1.4 要点总结 2. Abstract Factory2.1 模式介绍2.2 模式代码2.2.1 问题代码2.2.2 重构代码 2.3 模式类图2.4 要点总结 3. Prototype3.1 模式介绍3.2 模式代码3.3 模式类图3.4…

【AVRCP】Notification PDUs 深入解析与应用

目录 一、Notification PDUs 概述 二、GetPlayStatus:同步查询播放状态 2.1 命令功能与应用场景 2.2 请求格式(CT → TG) 2.3 响应格式(TG → CT) 2.4 注意事项 2.5 协议实现示例(伪代码) 三、RegisterNotification:异步事件订阅 3.1 命令概述 3.2 命令格式 …

MATLAB 控制系统设计与仿真 - 27

状态空间的标准型 传递函数和状态空间可以相互转换&#xff0c;接下来会举例如何有传递函数转成状态空间标准型。 对角标准型 当 G(s)可以写成&#xff1a; 即&#xff1a; 根据上图可知&#xff1a; 约当标准型 当 G(s)可以写成&#xff1a; 即&#xff1a; 根据上图…

linux 命令 cp

cp 是 Linux 中用于复制文件和目录的命令&#xff0c;基本功能是将源文件或目录复制到目标位置 基本语法 cp [选项] 源文件 目标文件 cp [选项] 源文件1 源文件2 ... 目标目录 常用选项 选项说明-i交互模式&#xff08;覆盖前询问确认&#xff09;-r 或 -R递归复制目录&#…

蓝桥杯高频考点——进制转换

进制转换 二进制转十进制代码演示 十六进制转十进制代码演示 十进制转K进制代码演示 任意进制之间的转换代码演示 二进制转十进制 代码演示 // 定义函数 calc&#xff0c;用于将字符转换为对应的数值 int calc(char c) {// 若字符 c 大于等于 9&#xff08;注&#xff1a;此处…

【算法百题】专题七_分治快排_专题八_分治归并

文章目录 前言分治快排题&#xff1a;043. [颜⾊分类&#xff08;medium&#xff09;](https://leetcode.cn/problems/sort-colors/description/)分析 044. [快速排序&#xff08;medium&#xff09;](https://leetcode.cn/problems/sort-an-array/description/)分析 045. [快速…

使用OBS进行webRTC推流参考

参考腾讯云官方文档&#xff1a; 云直播 OBS WebRTC 推流_腾讯云 说明非常详细&#xff0c;分为通过WHIP和OBS插件的形式进行推流。 注意&#xff1a;通过OBS插件的形式进行推流需要使用较低的版本&#xff0c;文档里有说明&#xff0c;需要仔细阅读。

(链表)面试题 02.07. 链表相交

给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数返回结果后&#xff…

Python----数据可视化(Pyecharts三:绘图二:涟漪散点图,K线图,漏斗图,雷达图,词云图,地图,柱状图折线图组合,时间线轮廓图)

1、涟漪特效散点图 from pyecharts.globals import SymbolType from pyecharts.charts import EffectScatter from pyecharts.faker import Faker from pyecharts import options as opts from pyecharts.globals import ThemeType # 绘制图表 es (EffectScatter(init_optsop…

IP风险度自检,互联网的安全“指南针”

IP地址就像我们的网络“身份证”&#xff0c;而IP风险度则是衡量这个“身份证”安全性的重要指标。它关乎着我们的隐私保护、账号安全以及网络体验&#xff0c;今天就让我们一起深入了解一下IP风险度。 什么是IP风险度 IP风险度是指一个IP地址可能暴露用户真实身份或被网络平台…

数据结构与算法-图论-拓扑排序

前置芝士 概念 拓扑排序&#xff08;Topological Sorting&#xff09;是对有向无环图&#xff08;DAG&#xff0c;Directed Acyclic Graph&#xff09;的顶点进行排序的一种算法。它将图中的所有顶点排成一个线性序列&#xff0c;使得对于图中的任意一条有向边 (u, v)&#x…

Gan网络公式了解

Gan网络 生成器和判别器是亦敌亦友的关系 对于生成模型&#xff0c;损失函数很难定义->所以我们可以将生成模型的输出交给判别模型进行处理&#xff0c;来分辨好坏。 生成器的损失是通过判别器的输出来计算的&#xff0c;而判别器的输出是一个概率值&#xff0c;我们可以通过…

解决linux mysql命令 bash: mysql: command not found 的方法

首先得知道mysql命令或mysqladmin命令的完整路径 比如mysql的路径是&#xff1a; /usr/local/mysql/bin/mysql&#xff0c;我们则可以这样执行命令&#xff1a; ln -s /usr/local/mysql/bin/mysql /usr/bin © 著作权归作者所有,转载或内容合作请联系作者 喜欢的朋友记得点…

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

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

【css酷炫效果】纯CSS实现立体纸张折叠动效

【css酷炫效果】纯CSS实现悬浮阴影扩散交互 缘创作背景html结构css样式完整代码基础版进阶版(3d 悬浮效果) 效果图 通过CSS box-shadow与transition属性实现悬浮阴影扩散交互&#xff0c;为元素添加细腻的悬浮反馈。 想直接拿走的老板&#xff0c;链接放在这里&#xff1a;htt…

案例5_1:单位数码管显示0

文章目录 文章介绍效果图仿真图5_1放置单位数码管 代码5_1.c 文章介绍 效果图 仿真图5_1 复制案例1_2的仿真图&#xff0c;在此基础上修改 注意&#xff1a;栅格大小需要缩小 放置单位数码管 代码5_1.c #include <reg52.h>#define uchar unsigned char #define uint un…

Linux centos7误删/boot拯救方法

1.进入救援模式 插入CentOS 7安装光盘&#xff0c;重启系统。在开机时按BIOS设置对应的按键&#xff08;通常是F2等&#xff09;&#xff0c;将启动顺序调整为CD - ROM优先。 系统从光盘启动后&#xff0c;选择“Troubleshooting”&#xff0c;然后选择“Rescue a CentOS s…

操作系统八股文整理(一)

操作系统八股文整理 一、进程和线程的区别二、进程与线程的切换过程一、进程切换进程切换的步骤&#xff1a; 二、线程切换线程切换的步骤&#xff1a; 三、进程切换与线程切换的对比四、上下文切换的优化 三、系统调用一、系统调用的触发二、从用户空间切换到内核空间三、执行…