微服务的“导航系统”:使用Spring Cloud Eureka实现服务注册与发现
在上一篇中,我们理解了微服务架构的核心理念以及Spring Cloud为我们提供的强大工具集。我们提到,微服务架构的一个核心挑战在于,服务实例的网络位置是动态的,服务之间需要一种机制来互相定位。
想象一下,你开了一家新店(一个微服务实例),你希望顾客(其他服务或客户端)能找到你。你会怎么做?
-
注册: 你会去工商局(服务注册中心)登记你的店名、地址、联系方式等信息。
-
发现: 顾客想找你这家店时,会去工商局查询你的信息,然后根据地址找过来。
-
健康检查/心跳: 你需要定期向工商局报告你还在正常营业(发送心跳),如果长时间不报告,工商局可能会认为你的店关门了,就不会再把你的信息给顾客。
Spring Cloud Netflix Eureka (简称 Eureka) 就是这样一个“工商局”。它包含两个核心组件:
-
Eureka Server (服务注册中心): 提供服务注册和发现的功能。所有服务提供者(Eureka Client)启动时向Eureka Server注册自己的信息(服务名、IP、端口、健康状况等),并定期发送心跳来维持注册状态。Eureka Server会维护一个所有已注册服务实例的清单。
-
Eureka Client (服务提供者/消费者):
-
作为服务提供者,它会向Eureka Server注册自己。
-
作为服务消费者,它会从Eureka Server拉取注册表信息,缓存到本地,并根据服务名(通常结合客户端负载均衡器如Spring Cloud LoadBalancer)找到目标服务的实例地址进行调用。
-
Eureka的核心优势在于其AP(可用性优先)设计哲学 (基于CAP理论)。 即使部分Eureka Server节点失效,只要客户端缓存了注册表信息,仍然可以进行服务调用。Eureka Server之间也会互相复制注册信息,实现高可用。
读完本文,你将能够:
-
搭建一个独立的Eureka Server。
-
将一个Spring Boot应用配置为Eureka Client,并将其注册到Eureka Server。
-
理解服务注册、服务发现和心跳机制的基本工作流程。
-
通过Eureka Server的Web界面查看已注册的服务。
准备好为你的微服务们建立一个可靠的“导航系统”了吗?
一、搭建Eureka Server (服务注册中心)
Eureka Server本身也是一个Spring Boot应用。
1. 创建Spring Boot项目 (Eureka Server):
使用Spring Initializr (start.spring.io) 或你的IDE创建一个新的Spring Boot项目,包含以下依赖:
-
Spring Web: Eureka Server提供Web界面和REST API。
-
Eureka Server: 核心依赖,用于构建Eureka注册中心。
Maven依赖 (pom.xml):
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><!-- Spring Cloud BOM (Bill of Materials) for version management -->
</dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version> <!-- 例如: 2022.0.4 --><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>
注意: 务必在<dependencyManagement>中引入spring-cloud-dependencies BOM来统一管理Spring Cloud各个组件的版本。spring-cloud.version需要与你的Spring Boot版本兼容(参考Spring Cloud官网的版本对应关系)。
2. 启用Eureka Server (@EnableEurekaServer):
在主启动类上添加@EnableEurekaServer注解。
package com.example.eurekaserver;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; // 导入@SpringBootApplication
@EnableEurekaServer // 标记这个应用是一个Eureka Server
public class EurekaServerApplication {public static void main(String[] args) {SpringApplication.run(EurekaServerApplication.class, args);}
}
3. 配置Eureka Server (application.yml 或 application.properties):
# application.yml for Eureka Server
server:port: 8761 # Eureka Server的默认端口spring:application:name: eureka-server # 应用名称, 会显示在Eureka管理界面eureka:instance:hostname: localhost # Eureka实例的主机名 (单机配置)# (可选) instance-id: ${spring.application.name}:${server.port}client:# 对于单机Eureka Server, 这两项通常设为false, 因为它自己就是注册中心, 不需要注册自己或从其他地方获取注册信息register-with-eureka: false # 是否将自己注册到Eureka Server (自己就是server, 所以是false)fetch-registry: false # 是否从Eureka Server获取注册信息 (自己就是server, 所以是false)service-url:# 对于单机模式, 这个地址指向自己 (通常不需要, 因为上面两项为false)# 但如果要搭建集群, 这里会配置其他Eureka Server节点的地址defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/# (可选) 关闭自我保护模式 (开发时方便快速看到服务下线, 生产环境不建议关闭)# server:# enable-self-preservation: false# eviction-interval-timer-in-ms: 5000 # 清理无效节点的时间间隔 (毫秒)
核心配置解释:
-
server.port: Eureka Server运行的端口,约定俗成为8761。
-
spring.application.name: 应用名,会显示在Eureka的管理界面。
-
eureka.client.register-with-eureka: false: 因为这个应用本身就是Eureka Server,所以它不需要向自己注册。
-
eureka.client.fetch-registry: false: 同理,它不需要从自己这里获取注册表。
-
eureka.client.service-url.defaultZone: 指定Eureka Server的地址。对于单机模式,这个配置虽然写了,但因为上面两项为false,实际作用不大。在Eureka Client端配置这个地址才至关重要。 当搭建Eureka Server集群时,这里会配置其他Peer节点的地址,用于节点间同步注册信息。
-
eureka.server.enable-self-preservation: Eureka的自我保护模式。在网络分区等情况下,如果Eureka Server在短时间内丢失了大量服务实例的心跳,它会进入自我保护模式,不再剔除这些“暂时失联”的实例,以防止因网络问题导致大量可用服务被错误移除。开发时为了快速看到服务下线效果,有时会临时关闭它,但生产环境通常应保持开启。
4. 运行Eureka Server:
启动这个Spring Boot应用。如果一切顺利,你可以在浏览器中访问 http://localhost:8761/,看到Eureka的Web管理界面。此时,界面上应该还没有任何服务实例注册。
二、创建服务提供者 (Eureka Client)
现在我们来创建一个简单的Spring Boot应用,并让它作为服务提供者注册到刚才搭建的Eureka Server上。
1. 创建Spring Boot项目 (例如 user-service):
包含以下依赖:
-
Spring Web: 提供REST API。
-
Eureka Discovery Client: 核心依赖,用于将应用注册为Eureka客户端。
-
(可选) Spring Boot Actuator: 用于健康检查。
Maven依赖 (pom.xml - user-service):
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><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-actuator</artifactId> <!-- 用于健康检查 --></dependency><!-- Spring Cloud BOM (确保与Eureka Server项目使用相同的BOM版本) -->
</dependencies><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>
2. 启用Eureka Client (@EnableDiscoveryClient 或 @EnableEurekaClient):
在主启动类上添加注解。@EnableDiscoveryClient是Spring Cloud提供的更通用的服务发现注解(可用于Eureka, Consul, Nacos等),而@EnableEurekaClient是专门针对Eureka的。推荐使用@EnableDiscoveryClient。
package com.example.userservice;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; // 推荐使用@SpringBootApplication
@EnableDiscoveryClient // 标记这个应用是一个服务发现客户端 (可以注册和发现服务)
// 或者 @EnableEurekaClient // 仅适用于Eureka
public class UserServiceApplication {public static void main(String[] args) {SpringApplication.run(UserServiceApplication.class, args);}
}
3. 配置Eureka Client (application.yml - user-service):
# application.yml for user-service
server:port: 8081 # 服务提供者运行的端口 (确保与Eureka Server端口不同)spring:application:name: user-service # 服务名称, 这是注册到Eureka Server上的关键标识!# 服务消费者会通过这个名称来查找服务实例eureka:client:# register-with-eureka: true # (默认即为true) 是否将自己注册到Eureka Server# fetch-registry: true # (默认即为true) 是否从Eureka Server获取注册信息service-url:defaultZone: http://localhost:8761/eureka/ # 指定Eureka Server的地址!instance:# (可选) 自定义实例ID, 默认为 ${spring.application.name}:${server.port}# instance-id: ${spring.application.name}:${random.value} # 可以使用随机值避免端口冲突时的ID冲突hostname: localhost # (可选) 如果需要让Eureka Server显示特定的主机名# (可选) 配置健康检查URL, Actuator的/actuator/health端点会自动被Eureka使用# health-check-url-path: /actuator/health# status-page-url-path: /actuator/info# (可选) 配置心跳间隔 (默认30秒)# lease-renewal-interval-in-seconds: 10# (可选) 配置服务过期时间 (默认90秒, 即如果90秒内没收到心跳, 实例被剔除)# lease-expiration-duration-in-seconds: 30
核心配置解释:
-
server.port: 这个服务提供者运行的端口,确保与Eureka Server的端口不同。
-
spring.application.name: 极其重要! 这是服务注册到Eureka Server时使用的服务名 (Service ID)。其他服务将来会通过这个服务名来发现和调用它。
-
eureka.client.service-url.defaultZone: 必须正确配置! 指向你的Eureka Server的地址。
-
eureka.instance.*: 可以配置实例相关的元数据,如实例ID、主机名、健康检查路径等。如果引入了spring-boot-starter-actuator,Eureka Client会自动使用/actuator/health端点作为健康检查URL。
4. (可选)创建一个简单的REST Controller (user-service):
package com.example.userservice.controller;import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/users")
public class UserController {@Value("${server.port}") // 注入当前服务端口, 方便演示private String serverPort;@GetMapping("/{id}")public String getUserById(@PathVariable Long id) {return "User details for ID " + id + " (from port: " + serverPort + ")";}
}
5. 运行服务提供者 (user-service):
启动这个user-service应用。稍等片刻(默认心跳间隔30秒,注册可能需要一点时间),然后刷新Eureka Server的管理界面 (http://localhost:8761/)。
你应该能在 "Instances currently registered with Eureka" 部分看到名为 USER-SERVICE (通常是大写) 的服务,以及它的实例信息(IP、端口、状态等)。状态初始可能是STARTING,之后会变为UP(如果健康检查通过)。
三、理解核心机制
-
服务注册 (Registration): Eureka Client(如user-service)启动后,会向eureka.client.service-url.defaultZone配置的Eureka Server地址发送注册请求,包含自己的服务名、IP、端口、健康状况等信息。
-
服务续约/心跳 (Renewal/Heartbeat): Client会定期(默认30秒)向Server发送心跳,告知Server自己仍然存活。如果Server在一定时间内(默认90秒)没有收到某个实例的心跳,会认为该实例已下线,并将其从注册表中剔除(除非开启了自我保护模式且触发了保护条件)。
-
服务发现 (Discovery): 其他Client(服务消费者)启动时或定期(默认30秒)从Eureka Server拉取最新的服务注册表信息,并缓存到本地。当需要调用某个服务时,它会从本地缓存的注册表中根据服务名查找可用的实例列表。
-
服务下线 (Cancellation): Client在正常关闭时,会向Server发送一个取消注册的请求。
四、高可用Eureka Server集群 (简述)
在生产环境中,单个Eureka Server节点是单点故障。通常会搭建Eureka Server集群来实现高可用。
配置集群的关键在于让每个Eureka Server节点知道其他节点的存在,并通过eureka.client.service-url.defaultZone互相指定对方的地址(但仍然将register-with-eureka和fetch-registry设为true,因为它们既是Server也是Client,需要同步注册信息)。
例如,两个节点的集群配置 (application-peer1.yml):
server:port: 8761
spring:application:name: eureka-server
eureka:instance:hostname: peer1 # 或真实IP/域名client:register-with-eureka: true # 注册到其他peerfetch-registry: true # 从其他peer获取信息service-url:defaultZone: http://peer2:8762/eureka/ # 指向另一个节点
application-peer2.yml 对应配置 peer1:8761。
客户端的defaultZone则配置所有Eureka Server节点的地址,用逗号分隔。
五、总结:迈出微服务的第一步
通过搭建Eureka Server和配置Eureka Client,我们成功地让一个微服务实例(user-service)注册到了服务注册中心,并且可以通过Eureka的Web界面查看到它的状态。这为后续的服务间调用打下了坚实的基础。
Spring Cloud Netflix Eureka提供了一种相对简单且经过广泛验证的服务注册与发现解决方案。虽然Netflix已将其置于维护模式,但它在许多现有系统中仍被大量使用,并且其AP设计理念对于理解服务发现非常重要。
在后续的文章中,我们将看到服务消费者如何利用从Eureka获取到的信息,结合客户端负载均衡器来调用这个user-service。我们也会在适当的时候介绍更新的服务发现组件,如Nacos或Consul。
相关文章:
微服务的“导航系统”:使用Spring Cloud Eureka实现服务注册与发现
在上一篇中,我们理解了微服务架构的核心理念以及Spring Cloud为我们提供的强大工具集。我们提到,微服务架构的一个核心挑战在于,服务实例的网络位置是动态的,服务之间需要一种机制来互相定位。 想象一下,你开了一家新…...

geoserver发布arcgis瓦片地图服务(最新版本)
第一步:下载geoserver服务,进入bin目录启动 需要提前安装好JDK环境,1.8及以上版本 安装完成,页面访问端口,进入控制台界面,默认用户名密码admin/geoserver 第二步:下载地图 破解版全能电子地图下载器&…...

多边形,矩形,长方体设置
在cesium中,我们可以通过既有的库来进行对地图的构建 // 向场景中添加一个几何体(立方体) scene.primitives.add(new Cesium.Primitive({// 定义几何体实例geometryInstances: new Cesium.GeometryInstance({// 使用BoxGeometry.fromDimensions方法创建…...
Spring Boot 框架概述
1. 简介 Spring Boot 是由 Pivotal 团队开发的一个用于简化 Spring 应用开发的框架。它通过提供默认配置、嵌入式服务器和自动配置等特性,让开发者能够更快速地构建独立的、生产级别的 Spring 应用。 Spring Boot 的主要特点包括: 快速创建独立的 Spri…...

(C语言)超市管理系统(测试版)(指针)(数据结构)(二进制文件读写)
目录 前言: 源代码: product.h product.c fileio.h fileio.c main.c 代码解析: fileio模块(文件(二进制)) 写文件(保存) 函数功能 代码逐行解析 关键知识点 读文…...
React百日学习计划-Grok3
关键点 研究表明,100天内学习React是可行的,尤其是你已有HTML、JS和CSS基础。该计划包括基础知识、hooks、状态管理、路由、样式化及综合项目,适合初学者。建议每天花2-3小时学习,结合免费教程和社区支持。 开始学习 学习React…...
一文辨析Java基本数据类型与包装类
Java 基本数据类型与包装类深度解析 前言一、Java 基本数据类型详解1.1 数值型1.1.1 整型1.1.2 浮点型 1.2 字符型1.3 布尔型 二、Java 包装类详解2.1 包装类与基本数据类型的对应关系2.2 包装类的常用方法 三、基本数据类型与包装类的转换3.1 装箱(Boxingÿ…...
Java游戏服务器开发流水账(3)游戏数据的缓存简介
简介 游戏服务器数据缓存是一种在游戏服务器运行过程中,用于临时存储经常访问的数据的技术手段,旨在提高游戏性能、降低数据库负载以及优化玩家体验。游戏开发中数据的缓存可以使用Java自身的内存也可以使用MemCache,Redis,注意M…...
SiLM59xx系列:高可靠性隔离驱动架构在新能源与工业电源中的关键设计解析
SiLM59xx系列产品选型: SiLM5932SHOCG-DG SiLM5992SHCG-DG SiLM5991SHCG-DG SiLM5932SHOCG-AQ SiLM5992SHCG-AQ SiLM5991SHCG-AQ 一、高功率密度驱动的核心挑战与解决方案 高压场景下的驱动需求 在新能源汽车主逆变器、光伏逆变器及工业电机控制…...

nRF Connect 下载
官方下载路径 点击,或往下拉 选对应的版本 下载成功,数字代表版本好...

基于Arduino的贪吃蛇游戏机
3D 打印迷你贪吃蛇游戏机: 在数字娱乐高度发达的今天,我们常常怀念那些经典的复古游戏。其中,贪吃蛇游戏无疑是许多人童年的记忆。今天,我将带你走进一个有趣的 DIY 项目——3D 打印迷你贪吃蛇游戏机。这个项目不仅能够让你重温经…...
talk-linux 不同用户之间终端通信
好的!下面是一个完整的指南和脚本,用于在两台 Linux 主机上配置并使用 talk 聊天功能(假设它们在同一个局域网内)。 ⸻ 🧾 一、需求说明 我们需要在两台主机上: 1. 安装 talk 和 talkd 2. 启用 talkd 服…...

【PmHub后端篇】Redis分布式锁:保障PmHub流程状态更新的关键
在分布式系统中,确保数据一致性和操作的正确执行是至关重要的。PmHub项目中,通过集成Redis分布式锁来保障流程状态更新,这是一个非常关键的技术点,以下将详细介绍其原理、实现。 1 本地锁的问题 1.1 常见的本地锁 在Java中&…...
MySQL基础入门:MySQL简介与环境搭建
引言 在数字化转型浪潮中,MySQL作为数据存储的"基石引擎",支撑着从电商交易到金融风控的各类核心业务。其高并发处理能力、灵活的架构设计及跨平台兼容性,使其成为开发者技术栈中的"常青树"。本章节将通过历史溯源、技术…...
力扣-543.二叉树的直径
题目描述 给你一棵二叉树的根节点,返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 class Solution { public:int maxLength(TreeNode *…...

Starrocks的主键表涉及到的MOR Delete+Insert更新策略
背景 写这个文章的作用主要是做一些总结和梳理,特别是正对大数据场景下的实时写入更新策略 COW 和 MOR 以及 DeleteInsert 的技术策略的演进, 这也适用于其他大数据的计算存储系统。该文章主要参考了Primary Key table. 分析总结 Starrocks 的主键表主…...

《操作系统真象还原》第十四章(2)——文件描述符、文件操作基础函数
文章目录 前言文件描述符简介文件描述符原理文件描述符实现修改thread.h修改thread.c 文件操作相关的基础函数inode操作相关函数文件相关函数编写file.h编写file.c 目录相关函数完善fs/dir.h编写fs/dir.c 路径解析相关函数实现文件检索功能修改fs.h继续完善fs.c makefile 结语 …...

EMQX v5.0通过连接器和规则同步数据
1 概述 EMQX数据集成功能,帮助用户将所有的业务数据无需额外编写代码即可快速完成处理与分发。 数据集成能力由连接器和规则两部分组成,用户可以使用数据桥接或 MQTT 主题来接入数据,使用规则处理数据后,再通过数据桥接将数据发…...

2. 盒模型/布局模块 - 响应式产品展示页_案例:电商产品网格布局
2. 盒模型/布局模块 - 响应式产品展示页 案例:电商产品网格布局 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><style type"text/css">:root {--primary-color…...

LVGL的三层屏幕结构
文章目录 🌟 LVGL 的三层屏幕架构1. **Top Layer(顶层)**2. **System Layer(系统层)**3. **Active Screen(当前屏幕层)** 🧠 总结对比🔍 整体作用✅ 普通屏幕层对象&…...

【PDF】使用Adobe Acrobat dc添加水印和加密
【PDF】使用Adobe Acrobat dc添加水印和加密 文章目录 [TOC](文章目录) 前言一、添加保护加密口令二、添加水印三、实验四、参考文章总结 实验工具: 1.Adobe Acrobat dc 前言 提示:以下是本篇文章正文内容,下面案例可供参考 一、添加保护加…...
AI 搜索引擎 MindSearch
背景 RAG是一种利用文档减少大模型的幻觉,AI搜索也是 AI 搜索引擎 MindSearch 是一个开源的 AI 搜索引擎框架,具有与 Perplexity.ai Pro 相同的性能。您可以轻松部署它来构建您自己的搜索引擎,可以使用闭源 LLM(如 GPT、Claude…...

Windows下安装mysql8.0
一、下载安装离线安装包 (下载过了,可以跳过) 下载网站:MySQL :: Download MySQL Installerhttps://dev.mysql.com/downloads/installer/ 二、安装mysql 三、安装完成验证...
【android bluetooth 框架分析 02】【Module详解 7】【VendorSpecificEventManager 模块介绍】
1. 背景 我们在 gd_shim_module 介绍章节中,看到 我们将 VendorSpecificEventManager 模块加入到了 modules 中。 // system/main/shim/stack.cc modules.add<hci::VendorSpecificEventManager>();在 ModuleRegistry::Start 函数中我们对 加入的所有 module…...

水滴Android面经及参考答案
static 关键字有什么作用,它修饰的方法可以使用非静态的成员变量吗? static关键字在 Java 中有多种作用。首先,它可以用来修饰变量,被static修饰的变量称为静态变量。静态变量属于类,而不属于类的某个具体实例…...

工程师必读! 3 个最常被忽略的 TDR 测试关键细节与原理
TDR真的是一个用来看阻抗跟Delay的好工具,通过一个Port的测试就可以看到通道各个位置的阻抗变化。 可是使用上其实没这么单纯,有很多细节需要非常地小心,才可以真正地看到您想看的信息! 就让我们整理3个极为重要的TDR使用小细节&…...

C++中的各式类型转换
隐式转换: 基本类型的隐式转换: 当函数参数类型非精确匹配,但是可以转换的时候发生 如: void func1(double x){cout << x << endl; }void func2(char c){cout << c << endl; }int main(){func1(2);//…...
2025年阿里云ACP人工智能高级工程师认证模拟试题(附答案解析)
这篇文章的内容是阿里云ACP人工智能高级工程师认证考试的模拟试题。 所有模拟试题由AI自动生成,主要为了练习和巩固知识,并非所谓的 “题库”,考试中如果出现同样试题那真是纯属巧合。 1、在PAl-Studio实验运行完毕后,可以右键单…...
如何使用scp命令拉取其他虚拟机中的文件
使用 SCP 命令拉取远程虚拟机文件 scp(Secure Copy)是基于 SSH 协议的安全文件传输工具,可以在本地与远程主机之间复制文件。以下是使用scp从其他虚拟机拉取文件的详细指南: 一、基本语法 bash # 从远程主机复制到本地 scp [选…...

Nacos源码—9.Nacos升级gRPC分析七
大纲 10.gRPC客户端初始化分析 11.gRPC客户端的心跳机制(健康检查) 12.gRPC服务端如何处理客户端的建立连接请求 13.gRPC服务端如何映射各种请求与对应的Handler处理类 14.gRPC简单介绍 10.gRPC客户端初始化分析 (1)gRPC客户端代理初始化的源码 (2)gRPC客户端启动的源码…...