第一章:Spring Cloud 概述与环境搭建
1.1 什么是微服务架构
| 概念名称 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| 微服务架构 | 一种将单一应用程序拆分为一组小型服务的架构风格,每个服务运行在独立的进程中,通过轻量级通信机制(如 HTTP)进行交互。 | 解耦系统功能,提升可维护性、可扩展性和部署灵活性。 | 无(架构模式) | 需要配套服务治理、配置管理、监控等基础设施支持。 |
| 单体架构 | 所有功能模块集中在一个应用中,打包为单一部署单元(如 WAR)。 | 适用于小型项目,开发简单。 | 无 | 随着业务增长,代码臃肿,难以维护和扩展。 |
| 服务自治 | 每个微服务独立开发、测试、部署、升级,不依赖其他服务的发布周期。 | 提高团队协作效率和发布频率。 | 无 | 需统一技术栈或兼容通信协议。 |
| 服务间通信 | 微服务之间通过 REST API、RPC、消息队列等方式进行通信。 | 实现功能协作与数据交换。 | 使用 RestTemplate 或 Feign 调用其他服务接口 | 应考虑超时、重试、熔断等容错机制。 |
| 分布式数据管理 | 每个微服务拥有独立的数据库,避免共享数据库导致的耦合。 | 保证服务独立性。 | 无 | 跨服务事务需使用分布式事务方案(如 Saga)。 |
1.2 Spring Cloud 简介与核心组件
| 组件名称 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| Spring Cloud | 基于 Spring Boot 的微服务一站式解决方案,提供服务治理、配置管理、网关、容错等工具集。 | 快速构建分布式系统。 | 无 | 是一系列框架的集合,非单一框架。 |
| Eureka | 服务注册与发现组件,由服务端(Server)和客户端(Client)组成。 | 实现服务自动注册与发现。 | @EnableEurekaServer(服务端)
@EnableDiscoveryClient(客户端) | Netflix 已停止维护,生产环境可考虑替代方案(如 Nacos)。 |
| Ribbon | 客户端负载均衡器,集成在服务调用方。 | 在多个服务实例间均衡请求。 | RestTemplate 结合 @LoadBalanced | 已进入维护模式,建议使用 Spring Cloud LoadBalancer。 |
| OpenFeign | 声明式 REST 客户端,简化 HTTP API 调用。 | 以接口方式调用远程服务,无需手动拼接 URL。 | @FeignClient(name = "service-user") | 需配合 Eureka 或配置静态地址使用。 |
| Hystrix | 熔断器组件,提供服务降级、隔离、限流功能。 | 防止服务雪崩,提高系统容错能力。 | @HystrixCommand(fallbackMethod = "fallback") | 已停止更新,推荐使用 Resilience4j。 |
| Gateway | API 网关,提供路由、过滤、限流等功能。 | 统一入口,安全控制与请求转发。 | spring.cloud.gateway.routes 配置 | 替代 Zuul 2.x,基于 WebFlux 响应式编程。 |
| Config | 分布式配置中心,集中管理微服务配置。 | 实现配置外部化与动态刷新。 | @RefreshScope + /actuator/refresh | 支持 Git、Vault 等后端存储。 |
| Sleuth + Zipkin | 链路追踪组件,标识请求在微服务间的流转路径。 | 排查性能瓶颈与故障定位。 | 添加依赖并配置 Zipkin 地址 | 需配合消息中间件或 HTTP 上报。 |
1.3 Spring Cloud 与 Spring Boot 版本兼容性
| Spring Cloud 版本 | 发布时间 | 兼容 Spring Boot 版本 | 用途 | 注意事项 |
|---|
| Hoxton | 2019–2020 | 2.2.x – 2.3.x | 支持 Spring Boot 2.2+ 的主流版本 | 停止维护,不推荐新项目使用 |
| Ilford | 2021 | 2.4.x – 2.5.x | 适配 Spring Boot 2.4+ 配置变更 | 已结束生命周期 |
| 2021.0 (J) | 2021–2022 | 2.6.x | 支持 Spring Boot 2.6.x | 注意 Spring Boot 2.6 对循环引用的默认禁用 |
| 2022.0 (K) | 2022–2023 | 3.0.x – 3.1.x | 支持 Spring Boot 3.x,引入虚拟线程预览 | 需 JDK 17+,Jakarta EE 9+ |
| 2023.0 (L) | 2023–2024 | 3.2.x | 当前推荐版本,稳定支持 Spring Boot 3.2 | 推荐新项目使用 |
| 2023.1 (M) | 2024–2025 | 3.3.x | 最新版本,适配 Spring Boot 3.3 | 保持更新,注意 Breaking Changes |
注意事项:务必通过 Spring Cloud 官方文档 查看最新兼容性矩阵,避免版本冲突导致启动失败。
1.4 开发环境准备(JDK、Maven、IDE)
| 工具 | 推荐版本 | 用途 | 安装/配置示例 | 注意事项 |
|---|
| JDK | 17 或 21(LTS) | 运行 Java 程序 | 下载 Oracle JDK 或 OpenJDK,设置 JAVA_HOME | Spring Boot 3.x 要求 JDK 17+ |
| Maven | 3.6+ | 项目构建与依赖管理 | 安装后配置 settings.xml 镜像源(如阿里云) | 推荐使用国内镜像加速依赖下载 |
| IDE | IntelliJ IDEA 或 Eclipse | 代码编写与调试 | 安装 Spring Boot 插件 | IDEA 对 Spring 生态支持更佳 |
| Git | 2.30+ | 版本控制 | 安装后配置用户名与邮箱 | 用于拉取配置中心代码或协作开发 |
| Docker | 20.10+(可选) | 容器化部署 | 安装 Docker Desktop | 微服务部署时非常有用 |
1.5 创建第一个 Spring Cloud 项目(使用 Spring Initializr)
| 步骤 | 说明 | 示例值 | 注意事项 |
|---|
| 访问 Initializr | 打开 https://start.spring.io | 网页地址 | 可使用国内镜像(如 https://start.aliyun.com) |
| 选择项目类型 | Maven / Gradle | Maven | 推荐 Maven,生态更成熟 |
| 选择语言 | Java / Kotlin / Groovy | Java | 主流选择 |
| Spring Boot 版本 | 选择稳定版本 | 3.2.0 | 与 Spring Cloud 版本匹配 |
| Group | 项目组织名 | com.example | 通常为公司域名倒写 |
| Artifact | 项目名 | demo-cloud | 生成项目文件夹名 |
| Dependencies | 添加依赖 | Spring Web, Spring Cloud Discovery (Eureka Client) | 初学者可先添加 Eureka Client 和 Web |
| 生成项目 | 点击 “Generate” 下载 zip 包 | demo-cloud.zip | 解压后导入 IDE |
| 导入 IDE | 使用 IDEA 打开项目 | File → Open → 选择 pom.xml | 等待 Maven 自动下载依赖 |
| 启动类 | 确保主类存在且含 @SpringBootApplication | DemoCloudApplication.java | 运行 main 方法启动 |
第二章:服务注册与发现(Eureka)
2.1 Eureka 原理与架构
| 概念名称 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| Eureka Server | 服务注册中心,接收服务注册并提供服务发现功能。 | 集中管理服务实例信息。 | @EnableEurekaServer | 通常部署为集群避免单点故障 |
| Eureka Client | 集成在微服务中的客户端,负责注册自身并拉取服务列表。 | 实现服务自动注册与发现。 | @EnableDiscoveryClient | 所有微服务都应引入 |
| 服务注册 | Client 启动时向 Server 发送注册请求,包含 IP、端口、服务名等。 | 让其他服务能发现本服务。 | eureka.client.service-url.defaultZone=http://localhost:8761/eureka | 需正确配置注册地址 |
| 服务续约(Renewal) | Client 每 30 秒发送心跳到 Server,证明服务存活。 | Server 依据心跳判断服务状态。 | eureka.instance.lease-renewal-interval-in-seconds=30 | 默认 30 秒,可调整 |
| 服务下线 | Client 关闭时发送 DELETE 请求注销服务。 | 避免调用已停止的服务实例。 | 自动触发 | 若强制 kill,需依赖 Server 的失效剔除机制 |
| 失效剔除 | Server 默认每 60 秒扫描一次,移除超过 90 秒未续约的服务。 | 清理无效实例,保证服务列表准确。 | eureka.server.eviction-interval-timer-in-ms=60000 | 生产环境可优化频率 |
2.2 搭建 Eureka Server
| 方法/配置项 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
@EnableEurekaServer | 类注解 | 启用 Eureka 服务端功能 | @SpringBootApplication @EnableEurekaServer public class EurekaServerApp { } | 必须添加,否则不会启动 Eureka UI |
spring.application.name | application.yml | 设置服务名 | spring: application: name: eureka-server | 在 Eureka UI 中显示 |
server.port | application.yml | 设置端口号 | server: port: 8761 | Eureka 默认端口为 8761 |
eureka.client.register-with-eureka | application.yml | 是否将自己注册为客户端 | eureka: client: register-with-eureka: false | Server 通常设为 false |
eureka.client.fetch-registry | application.yml | 是否从 Server 拉取服务列表 | eureka: client: fetch-registry: false | Server 不需要拉取 |
eureka.client.service-url.defaultZone | application.yml | 指定对等节点地址(集群用) | eureka: client: service-url: defaultZone: http://peer1:8761/eureka | 单机可指向自己 |
2.3 服务提供者注册到 Eureka
| 方法/配置项 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
@EnableDiscoveryClient | 类注解 | 启用服务发现客户端 | @SpringBootApplication @EnableDiscoveryClient public class ProviderApp { } | Spring Cloud Commons 提供,通用 |
spring.application.name | application.yml | 设置服务在 Eureka 中的名称 | spring: application: name: service-provider | 必须设置,用于服务发现 |
server.port | application.yml | 设置服务端口 | server: port: 8081 | 可动态指定(如 port: 0) |
eureka.client.service-url.defaultZone | application.yml | 指定 Eureka Server 地址 | eureka: client: service-url: defaultZone: http://localhost:8761/eureka | 多个地址用逗号分隔 |
eureka.instance.instance-id | application.yml | 自定义实例 ID 显示 | eureka: instance: instance-id: ${spring.application.name}:${server.port} | 默认为主机名+端口,不易识别 |
2.4 服务消费者发现服务
| 方法/配置项 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
@LoadBalanced | RestTemplate 上的注解 | 启用 Ribbon 负载均衡 | @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } | 必须添加才能使用服务名调用 |
discoveryClient.getInstances() | 方法调用 | 获取指定服务的所有实例 | @Autowired private DiscoveryClient discoveryClient; public String callProvider() { List<ServiceInstance> instances = discoveryClient.getInstances("service-provider"); ServiceInstance instance = instances.get(0); String url = instance.getUri() + "/api/hello"; return restTemplate.getForObject(url, String.class); } | 手动实现负载均衡,不推荐 |
| 使用服务名调用 | RestTemplate 请求 URL | 通过服务名而非 IP 调用 | String url = "http://service-provider/api/hello"; return restTemplate.getForObject(url, String.class); | 需 @LoadBalanced 支持 |
@EnableDiscoveryClient | 类注解 | 启用服务发现功能 | 同 2.3 节 | 消费者也需注册到 Eureka |
2.5 Eureka 高可用集群配置
| 配置项 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
| 多个 Eureka Server 实例 | 不同端口运行多个 Server | 避免单点故障 | server.port=8761 / 8762 / 8763 | 可在同一机器用不同端口模拟 |
| 互相注册 | 每个 Server 配置其他 Server 地址 | 构成集群,同步服务信息 | eureka: client: service-url: defaultZone: http://peer2:8762/eureka | peer1 指向 peer2,peer2 指向 peer1 |
| 禁用自我保护(生产慎用) | 配置项 | 关闭自我保护模式 | eureka: server: enable-self-preservation: false | 默认开启,防止网络波动误删服务 |
| 设置主机名 | /etc/hosts 配置 | 模拟多节点域名 | 127.0.0.1 peer1 127.0.0.1 peer2 | 配合 application.yml 中的 eureka.instance.hostname 使用 |
| 实例健康检查 | 配置启用 | 使用 Spring Boot Actuator 健康检查 | eureka: client: healthcheck: enabled: true | 更准确判断服务状态 |
第三章:客户端负载均衡(Ribbon)
3.1 Ribbon 简介与工作原理
| 概念名称 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| Ribbon | Netflix 开源的客户端负载均衡器,集成在调用方,无需独立部署。 | 在服务消费者端实现负载均衡,避免集中式网关瓶颈。 | 通过 @LoadBalanced 注解启用 | 已进入维护模式,建议新项目使用 Spring Cloud LoadBalancer |
| 客户端负载均衡 | 负载均衡逻辑在服务调用方执行,调用前选择目标实例。 | 减少中间环节,提升性能与灵活性。 | RestTemplate 调用服务名 | 需维护本地服务列表缓存 |
| 服务列表拉取 | Ribbon 从 Eureka 获取服务实例列表并缓存到本地。 | 支持离线调用,降低对注册中心依赖。 | 自动完成 | 默认每 30 秒刷新一次 |
| 负载均衡策略 | 决定如何从多个实例中选择一个进行调用。 | 实现请求分发,避免单实例过载。 | 如轮询、随机、权重等 | 可自定义策略 |
ILoadBalancer 接口 | Ribbon 核心接口,定义负载均衡器行为。 | 管理服务器列表、选择服务器、健康检查。 | 实现类:ZoneAwareLoadBalancer | 开发者通常无需直接操作 |
IPing 接口 | 用于检测服务实例是否存活。 | 定期检查实例健康状态,剔除不可用节点。 | 实现类:PingUrl | 可配置自定义 Ping 策略 |
3.2 Ribbon 与 RestTemplate 集成
| @LoadBalanced | Bean 定义时的注解 | 为 RestTemplate 启用 Ribbon 负载均衡能力。 | @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } | 必须添加,否则无法解析服务名 |
| RestTemplate 调用服务名 | 使用服务名而非具体 IP:端口 | 实现基于服务名的负载均衡调用。 | String url = "http://service-provider/api/data"; String result = restTemplate.getForObject(url, String.class); | 服务名需与 Eureka 中注册名一致 |
| spring.cloud.loadbalancer.ribbon.enabled | application.yml 配置 | 强制启用 Ribbon(Spring Cloud 2020+ 默认禁用) | spring: cloud: loadbalancer: ribbon: enabled: true | 若使用旧版本 Ribbon 必须设置 |
| 依赖引入 | Maven 依赖 | 添加 Ribbon 支持(Spring Cloud 2020 前自动包含) | org.springframework.cloud:spring-cloud-starter-netflix-ribbon | 新版本需显式引入或使用 LoadBalancer |
3.3 自定义负载均衡策略
| 方法/配置项 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
IRule 接口 | Ribbon 策略接口,定义 choose() 方法选择实例。 | 实现自定义负载均衡逻辑。 | public class CustomRule implements IRule { @Override public Server choose(Object key) { // 自定义选择逻辑 } } | 必须返回非 null Server |
轮询策略(RoundRobinRule) | 默认策略,按顺序循环选择实例。 | 均匀分发请求。 | 不需代码,默认生效 | 适用于实例性能相近场景 |
随机策略(RandomRule) | 随机选择一个可用实例。 | 简单随机分发。 | @Bean public IRule randomRule() { return new RandomRule(); } | 可能导致负载不均 |
最小并发数(BestAvailableRule) | 选择并发请求数最少的实例。 | 优化响应速度。 | return new BestAvailableRule(); | 需配合并发监控 |
响应时间权重(WeightedResponseTimeRule) | 根据响应时间动态分配权重。 | 响应快的实例接收更多请求。 | return new WeightedResponseTimeRule(); | 初始无数据时退化为轮询 |
| 配置指定服务策略 | 为特定服务设置策略 | 实现差异化负载均衡。 | service-provider: ribbon: NFLoadBalancerRuleClassName: com.example.CustomRule | 服务名需与 Eureka 一致 |
3.4 饥饿加载与连接池配置
| 配置项 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
| 饥饿加载(eager-load) | 启动时立即初始化 Ribbon 客户端 | 避免首次调用超时。 | ribbon: eager-load: enabled: true clients: service-provider | 推荐生产环境开启 |
连接池配置(MaxAutoRetries) | 设置重试次数 | 处理瞬时失败。 | service-provider: ribbon: MaxAutoRetries: 1 MaxAutoRetriesNextServer: 1 | 避免重试风暴 |
连接超时(ConnectTimeout) | 建立连接的最大等待时间。 | 防止连接挂起。 | ribbon: ConnectTimeout: 5000 | 单位毫秒,建议 5000 以内 |
读取超时(ReadTimeout) | 读取响应的最大等待时间。 | 防止响应阻塞。 | ribbon: ReadTimeout: 10000 | 根据业务响应时间设置 |
并发连接数(MaxTotalHttpConnections) | 最大总连接数。 | 控制资源使用。 | ribbon: MaxTotalHttpConnections: 500 | 需评估服务并发量 |
每主机连接数(MaxConnectionsPerHost) | 每个主机最大连接数。 | 避免单实例连接过多。 | ribbon: MaxConnectionsPerHost: 50 | 合理分配连接资源 |
第四章:声明式服务调用(OpenFeign)
4.1 OpenFeign 概述与优势
| 概念名称 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| OpenFeign | 声明式 REST 客户端,通过接口 + 注解方式调用 HTTP 服务。 | 简化远程调用,像调用本地方法一样调用远程服务。 | @FeignClient(name = "service-user") public interface UserClient { @GetMapping("/user/{id}") User findById(@PathVariable Long id); } | 需启用 @EnableFeignClients |
| 声明式调用 | 通过接口定义服务契约,无需手动构建 HTTP 请求。 | 提高开发效率,降低出错概率。 | 见上例 | 接口方法签名即为 API 契约 |
| 与 Ribbon 集成 | Feign 默认集成 Ribbon 实现负载均衡。 | 自动选择服务实例。 | 无需额外配置 | 依赖服务发现机制 |
| 与 Hystrix 集成 | 支持熔断与降级(旧版本)。 | 提高系统容错能力。 | fallback = UserClientFallback.class | Hystrix 已停更,可替换为 Resilience4j |
| 编码器/解码器 | 自动序列化请求参数与反序列化响应结果。 | 支持 JSON、XML 等格式。 | 默认使用 Jackson | 可自定义编解码器 |
4.2 OpenFeign 接口定义与注解使用
| 注解 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
@FeignClient | 接口级注解 | 声明 Feign 客户端,绑定服务名。 | @FeignClient(name = "service-order") public interface OrderClient { } | name 必须与 Eureka 服务名一致 |
@RequestMapping | 方法级注解 | 定义请求路径与方法。 | @RequestMapping(value = "/api/order", method = RequestMethod.GET) | 支持 GET、POST 等 |
@GetMapping | 方法级注解 | 简化 GET 请求定义。 | @GetMapping("/api/order/{id}") | Spring MVC 风格 |
@PostMapping | 方法级注解 | 定义 POST 请求。 | @PostMapping("/api/order") | 配合 @RequestBody 使用 |
@PathVariable | 参数级注解 | 绑定 URL 路径变量。 | String get(@PathVariable("id") Long id) | 名称需匹配 |
@RequestParam | 参数级注解 | 绑定查询参数。 | String list(@RequestParam("page") int page) | 生成 ?page=1 |
@RequestBody | 参数级注解 | 将参数序列化为请求体。 | void create(@RequestBody Order order) | 用于 POST/PUT |
@RequestHeader | 参数级注解 | 添加请求头。 | String auth(@RequestHeader("Authorization") String token) | 传递认证信息 |
4.3 Feign 客户端配置与日志
| 配置项/方法 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
@EnableFeignClients | 主类注解 | 启用 Feign 客户端扫描。 | @SpringBootApplication @EnableFeignClients public class App { } | 必须添加 |
日志级别(Logger.Level) | 设置 Feign 日志详细程度。 | 调试请求与响应。 | logging: level: com.example.client.OrderClient: DEBUG | 需设置包或接口级别 |
| NONE | 不记录日志 | 生产环境提升性能。 | Level.NONE | 默认级别 |
| BASIC | 记录请求方法、URL、响应状态。 | 基础调试。 | Level.BASIC | 推荐生产使用 |
| HEADERS | 记录请求/响应头信息。 | 调试认证、分页等头信息。 | Level.HEADERS | 日志量增加 |
| FULL | 记录请求/响应全部内容(含正文)。 | 全面调试,日志量大。 | Level.FULL | 仅开发环境使用 |
| 自定义配置类 | 为特定客户端配置 | 隔离配置,避免全局影响。 | @Configuration public class FeignConfig { @Bean public Logger.Level level() { return Logger.Level.FULL; } } | 不能被 @ComponentScan 扫到 |
4.4 Feign 超时与重试机制
| 配置项 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
connectTimeout | 设置建立连接超时时间。 | 防止连接长时间挂起。 | feign: client: config: default: connectTimeout: 5000 | 单位毫秒,建议 5000 |
readTimeout | 设置读取响应超时时间。 | 防止响应处理过长阻塞线程。 | feign: client: config: default: readTimeout: 10000 | 根据业务响应时间设置 |
| 请求压缩 | 启用请求体压缩 | 减少网络传输量。 | feign: compression: request: enabled: true | 适用于大请求体 |
| 响应压缩 | 启用响应体压缩 | 减少响应数据大小。 | feign: compression: response: enabled: true | 服务端需支持 Gzip |
| 重试机制 | 默认不重试,需集成 Hystrix 或自定义 | 处理临时故障。 | 需结合 Resilience4j 或 RetryTemplate | 避免对非幂等操作重试 |
4.5 Feign 与 Ribbon 集成原理
| 概念/机制 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| 动态代理 | Feign 在启动时为 @FeignClient 接口生成代理对象。 | 将接口调用转换为 HTTP 请求。 | 无需代码,自动完成 | 使用 JDK 动态代理或 CGLIB |
请求拦截器(RequestInterceptor) | 在请求发送前添加公共逻辑。 | 添加 Token、日志、Header 等。 | public class AuthInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { template.header("Authorization", "Bearer xxx"); } } | 实现 RequestInterceptor 接口 |
| 与 Ribbon 协作流程 | Feign → Ribbon → Eureka | 实现服务发现与负载均衡。 | 调用 OrderClient.findById(1L) → Ribbon 选择实例 → 发送 HTTP | 透明集成,开发者无感 |
| 负载均衡执行点 | 在 Feign 发送请求前,由 Ribbon 选择目标实例。 | 实现客户端负载均衡。 | 基于 IRule 策略选择 | 可自定义策略 |
| 默认客户端 | Feign 默认使用 JDK HttpURLConnection | 轻量但功能有限。 | 无配置 | 可替换为 Apache HttpClient 或 OKHttp |
第五章:服务容错与熔断(Hystrix)
5.1 Hystrix 熔断器模式原理
| 概念名称 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| 熔断器模式 | 一种保护机制,当依赖服务故障率超过阈值时,自动”熔断”请求,防止雪崩。 | 隔离故障服务,避免资源耗尽。 | 无需代码,由 Hystrix 自动管理 | 类似电路保险丝 |
| 三种状态:Closed | 正常状态,请求正常通过。 | 允许调用依赖服务。 | — | 当失败率低于阈值时保持 |
| 三种状态:Open | 熔断开启,拒绝所有请求。 | 快速失败,保护系统资源。 | — | 达到失败阈值后进入 |
| 三种状态:Half-Open | 半开状态,尝试放行少量请求探测服务是否恢复。 | 实现自动恢复机制。 | — | 经过 sleepWindow 后进入 |
| 断路器开启条件 | 默认:10秒内20次请求,失败率 ≥ 50%。 | 触发熔断逻辑。 | 可配置属性控制 | 可通过参数调整灵敏度 |
| 资源隔离 | Hystrix 使用线程池或信号量隔离不同服务调用。 | 防止单个服务故障影响整体。 | threadPoolKey 指定线程池 | 推荐使用线程池隔离 |
| 请求超时 | 默认1秒,超时则视为失败。 | 避免长时间阻塞线程。 | 可配置 command.timeout.in.milliseconds | 根据业务合理设置 |
5.2 Hystrix 命令定义(@HystrixCommand)
| 方法/注解 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
@HystrixCommand | 方法级注解,将方法包装为 HystrixCommand。 | 实现服务调用的熔断与降级。 | @HystrixCommand(fallbackMethod = "fallback") public String callService() { return restTemplate.getForObject("http://service-b/hello", String.class); } | 必须配合 @EnableCircuitBreaker 或 @SpringBootApplication 使用 |
fallbackMethod | 指定降级方法名。 | 异常或熔断时执行备用逻辑。 | fallbackMethod = "fallback" | 降级方法签名必须兼容(参数一致,返回类型相同) |
commandProperties | 配置命令级属性。 | 控制超时、线程池、熔断规则等。 | @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value="3000") | 可设置多个属性 |
threadPoolKey | 指定线程池标识。 | 实现资源隔离,避免共享线程池阻塞。 | @HystrixCommand(threadPoolKey = "UserServicePool") | 不同服务应使用不同线程池 |
groupKey | 命令组名,用于监控分类。 | 逻辑分组,便于仪表盘查看。 | groupKey = "UserService" | 默认为类名 |
commandKey | 命令标识,用于监控。 | 唯一标识一个 Hystrix 命令。 | commandKey = "getUserById" | 默认为方法名 |
5.3 服务降级处理
| 方法/配置项 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
| 本地降级方法 | 在同一类中定义 fallback 方法。 | 提供本地备用响应。 | public String fallback(Long id) { return "Default User"; } | 必须与原方法签名兼容 |
| 全局降级 | 实现 FallbackFactory,处理所有异常情况。 | 统一处理降级逻辑。 | public class UserClientFallbackFactory implements FallbackFactory<UserClient> { @Override public UserClient create(Throwable cause) { return id -> "Fallback due to " + cause.getMessage(); } } | 用于 Feign 集成 |
| 降级策略选择 | 根据业务场景返回默认值、缓存数据或空结果。 | 保证用户体验不中断。 | 返回静态页面、缓存数据等 | 避免降级逻辑本身出错 |
| 异常传递 | fallback 方法可接收 Throwable 参数。 | 分析失败原因并记录日志。 | public String fallback(Long id, Throwable t) { } | 有助于问题排查 |
| 禁用降级 | 不设置 fallbackMethod。 | 强制暴露异常,便于调试。 | @HystrixCommand | 生产环境不推荐 |
5.4 Hystrix 仪表盘监控
| 配置项/组件 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
@EnableHystrixDashboard | 主类注解 | 启用 Hystrix 仪表盘。 | @SpringBootApplication @EnableHystrixDashboard public class DashboardApp { } | 需引入 spring-cloud-starter-netflix-hystrix-dashboard |
/hystrix 端点 | 访问地址 | 进入仪表盘首页。 | http://localhost:8080/hystrix | 输入被监控服务的 /actuator/hystrix.stream |
/actuator/hystrix.stream | 被监控服务暴露的流端点 | 实时推送 Hystrix 执行数据。 | http://client-service/actuator/hystrix.stream | 需引入 spring-boot-starter-actuator |
| Turbine(聚合) | 聚合多个服务的 stream 数据。 | 统一监控微服务集群。 | 需单独部署 Turbine 服务 | 支持集群聚合 |
| 仪表盘图形解读 | 实心圆颜色表示健康度(绿色=健康,红色=异常) | 直观查看服务状态。 | — | 圆圈大小表示请求量 |
| 监控延迟 | 数据上报有轻微延迟(秒级)。 | 实时性非毫秒级。 | — | 不适用于精确性能分析 |
5.5 Hystrix 请求缓存与合并
| 功能 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
请求缓存(@CacheResult) | 缓存相同参数的调用结果。 | 减少重复请求,提升性能。 | @HystrixCommand(fallbackMethod = "fallback") @CacheResult(cacheKeyMethod = "getCacheKey") public String getData(String id) { ... } | 需实现缓存键生成方法 |
缓存键生成(cacheKeyMethod) | 指定生成缓存键的方法。 | 控制缓存粒度。 | public String getCacheKey(String id) { return id; } | 必须返回可哈希对象 |
缓存清理(@CacheRemove) | 清除指定缓存。 | 数据变更后同步缓存。 | @CacheRemove(commandKey = "getData") public void updateData(String id) { ... } | 必须指定 commandKey |
请求合并(@HystrixCollapser) | 将多个请求合并为一次批量调用。 | 减少远程调用次数,提升吞吐。 | @HystrixCollapser(batchMethod = "batchGet", scope = Scope.REQUEST) | 适用于高并发小请求 |
批量方法(batchMethod) | 定义合并后的批量处理逻辑。 | 实现批量查询或处理。 | public List<String> batchGet(List<String> ids) { ... } | 参数为 List,返回 List |
合并窗口(collapserProperties) | 设置合并时间窗口。 | 控制合并频率。 | @HystrixProperty(name="timerDelayInMilliseconds", value="10") | 默认 10ms |
第六章:API 网关(Spring Cloud Gateway)
6.1 网关的作用与 Spring Cloud Gateway 架构
| 概念名称 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| API 网关 | 微服务系统的统一入口,负责路由、过滤、认证、限流等。 | 解耦客户端与微服务,提升安全与可维护性。 | — | 所有请求先经过网关 |
| 路由(Route) | 网关的基本单元,包含 ID、目标 URI、断言和过滤器。 | 定义请求转发规则。 | — | 动态匹配请求并转发 |
| 断言(Predicate) | 匹配 HTTP 请求的条件(如路径、方法、头信息)。 | 判断是否应用某条路由。 | Path=/api/user/** | 支持多种匹配方式 |
| 过滤器(Filter) | 在请求前后执行逻辑(如修改头、日志、鉴权)。 | 实现横切关注点。 | AddRequestHeader=X-Request-Foo, Bar | 分为全局与局部 |
| WebFlux | 基于 Reactor 的响应式编程框架。 | 支持高并发非阻塞 I/O。 | 使用 Mono/Flux | 需适应响应式编程模型 |
| Netty | 底层网络通信框架(可选)。 | 提升性能,支持长连接。 | — | 默认使用 Netty 作为服务器 |
6.2 路由配置(Route)与断言(Predicate)
| 配置项 | 语法(application.yml) | 用途 | 代码示例 | 注意事项 |
|---|
id | 路由唯一标识 | 便于管理和监控 | id: user-service-route | 必须唯一 |
uri | 目标服务地址 | 请求转发的目标 | uri: lb://service-user | lb:// 表示使用负载均衡 |
predicates | 断言列表,匹配请求 | 决定是否应用此路由 | predicates: - Path=/api/user/** | 多个断言为”与”关系 |
Path | 匹配请求路径 | 实现基于路径的路由 | - Path=/api/order/** | 支持 Ant 风格 |
Method | 匹配 HTTP 方法 | 控制请求类型 | - Method=GET,POST | 可指定多个方法 |
Header | 匹配请求头 | 实现基于头信息的路由 | - Header=X-Request-Id, \d+ | 支持正则 |
Query | 匹配查询参数 | 基于参数内容路由 | - Query=name 或 - Query=name,abc | — |
After / Before | 匹配时间 | 实现灰度发布或定时路由 | - After=2025-01-01T00:00:00+08:00 | 使用 ISO-8601 时间格式 |
6.3 过滤器(Filter)的使用(全局与局部)
| 过滤器类型 | 语法(application.yml) | 用途 | 代码示例 | 注意事项 |
|---|
| 局部过滤器 | 作用于特定路由 | 实现路由级逻辑 | filters: - AddRequestHeader=X-Auth, token123 - AddResponseHeader=Access-Control-Allow-Origin, * | 执行顺序由定义顺序决定 |
| 全局过滤器 | 作用于所有路由 | 实现通用功能(如鉴权、日志) | 实现 GlobalFilter 接口 | 无需在配置中声明 |
AddRequestHeader | 添加请求头 | 传递认证或上下文信息 | - AddRequestHeader=Authorization, Bearer xxx | 原请求头不受影响 |
AddResponseHeader | 添加响应头 | 控制客户端行为 | - AddResponseHeader=Server, Gateway | 常用于跨域 |
RewritePath | 重写路径 | 转发前修改请求路径 | - RewritePath=/api/(?<segment>.*), /${segment} | 使用正则捕获组 |
StripPrefix | 剥离路径前缀 | 去除网关前缀再转发 | - StripPrefix=1 | 剥离第一级路径 |
| 自定义全局过滤器 | Java 类实现 | 实现复杂逻辑(如权限校验) | public class AuthFilter implements GlobalFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { ... } } | 注意响应式编程的异步特性 |
6.4 限流与跨域配置
| 配置项/组件 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
RequestRateLimiter | 限流过滤器,基于 Redis + Lua 实现。 | 控制请求频率,防止滥用。 | filters: - name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 10 redis-rate-limiter.burstCapacity: 20 | 需引入 spring-boot-starter-data-redis-reactive |
replenishRate | 每秒补充的令牌数。 | 控制平均速率。 | redis-rate-limiter.replenishRate: 10 | 即每秒允许10个请求 |
burstCapacity | 令牌桶容量。 | 允许突发流量。 | redis-rate-limiter.burstCapacity: 20 | 突发最多20个请求 |
key-resolver | 限流键解析器,决定按什么维度限流。 | 实现用户级或 IP 级限流。 | args: key-resolver: "#{@ipKeyResolver}" | 需在 Spring 容器中定义 Bean |
| 跨域配置(CORS) | 全局配置允许的源、方法、头 | 解决浏览器跨域问题。 | spring: cloud: gateway: cors: allowed-origins: http://localhost:3000 allowed-methods: GET,POST allowed-headers: "*" | 生产环境应精确配置 |
全局 WebFilter 实现 CORS | 自定义过滤器处理 OPTIONS 预检 | 更灵活控制跨域逻辑 | 实现 GlobalFilter 拦截 OPTIONS 请求 | 优先级需高于其他过滤器 |
6.5 动态路由与配置中心集成
| 功能 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| 动态路由 | 路由规则可在运行时修改,无需重启网关。 | 适应快速变化的业务需求。 | 通过 POST 请求 /actuator/gateway/routes 修改 | 需启用 actuator 端点 |
/actuator/gateway/routes | 查看当前所有路由 | 监控与调试 | GET http://gateway/actuator/gateway/routes | 返回 JSON 列表 |
/actuator/gateway/routes/{id} | 增删改指定路由 | 实现动态管理 | POST 添加,DELETE 删除 | Content-Type: application/json |
| 与 Config Server 集成 | 从配置中心拉取路由配置。 | 实现集中化、版本化管理。 | spring: cloud: config: uri: http://config-server | 配置文件中定义 spring.cloud.gateway.routes |
| 自动刷新路由 | 配置变更后自动更新网关路由。 | 零停机更新路由规则。 | 发送 POST 到 /actuator/refresh | 需配合 @RefreshScope |
| 路由持久化 | 将路由存储在数据库或配置中心。 | 避免内存丢失,支持多实例同步。 | 使用 Git、Nacos、数据库等 | 推荐生产环境使用 |
第七章:配置中心(Spring Cloud Config)
7.1 分布式配置管理需求
| 概念名称 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| 配置外化 | 将配置从应用代码中剥离,集中管理。 | 适应不同环境(dev/test/prod)的配置差异。 | application-dev.yml、application-prod.yml | 避免敏感信息硬编码 |
| 配置集中化 | 所有微服务的配置统一存储在配置中心。 | 提高管理效率,避免配置散落。 | Git 仓库中存放 config-repo | 推荐使用版本控制系统 |
| 动态刷新 | 配置变更后无需重启服务即可生效。 | 减少发布停机时间,提升运维效率。 | @RefreshScope + /actuator/refresh | 仅支持部分 Bean |
| 环境隔离 | 不同环境使用不同的配置文件。 | 防止测试配置误用于生产。 | {application}-{profile}.yml | profile 对应环境标识 |
| 安全管理 | 敏感配置(如密码)加密存储。 | 防止配置泄露。 | 使用 symmetric/asymmetric 加密 | 推荐使用 Vault 替代明文 |
| 版本控制 | 配置变更可追溯、可回滚。 | 保证配置变更的可审计性。 | Git 提交历史记录 | 便于排查配置问题 |
7.2 Config Server 搭建与 Git 后端存储
| 方法/配置项 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
@EnableConfigServer | 主类注解 | 启用配置服务器功能。 | @SpringBootApplication @EnableConfigServer public class ConfigServerApp { } | 必须添加 |
spring.cloud.config.server.git.uri | 指定 Git 仓库地址 | 存储配置文件的远程仓库。 | git: uri: https://github.com/user/config-repo.git | 支持本地路径或 SSH |
spring.cloud.config.server.git.search-paths | 指定配置文件搜索路径 | 在仓库中查找配置的子目录。 | search-paths: /config/{application} | 支持通配符 |
spring.cloud.config.server.git.username / password | Git 认证信息 | 访问私有仓库。 | username: user password: pass | 生产环境建议使用 SSH 或 Token |
| 配置文件命名规则 | {application}-{profile}.yml | Config Server 查找配置的规则。 | service-user-dev.yml、service-order-prod.yml | application 对应服务名,profile 对应环境 |
/{application}/{profile} 端点 | 访问配置的 HTTP 接口 | 获取指定服务和环境的配置。 | GET http://config-server/user/dev | 返回 JSON 格式的配置 |
| 多仓库支持 | 为不同服务配置不同 Git 仓库。 | 实现配置隔离。 | repos: service-user: pattern: user-** uri: https://git/user-config | pattern 匹配服务名 |
7.3 Config Client 获取配置
| 配置项 | 语法(bootstrap.yml) | 用途 | 代码示例 | 注意事项 |
|---|
spring.application.name | 服务名称 | 决定从哪个配置文件加载。 | spring: application: name: service-user | 必须设置,对应 {application} |
spring.profiles.active | 激活的环境配置 | 决定加载哪个 profile 的配置。 | profiles: active: dev | 可通过启动参数指定 |
spring.cloud.config.uri | Config Server 地址 | 客户端连接配置中心。 | cloud: config: uri: http://config-server:8888 | 必须在 bootstrap.yml 中配置 |
bootstrap.yml 加载顺序 | 早于 application.yml 加载 | 确保在应用启动前获取配置。 | 文件名必须为 bootstrap.yml | Spring Cloud 3.x 中需启用 config starter |
@Value 或 @ConfigurationProperties | 注入配置值 | 在代码中使用外部配置。 | @Value("${user.timeout:5000}") private int timeout; | 支持默认值 |
| 配置优先级 | 本地配置 < 远程配置 < 命令行参数 | 控制配置覆盖顺序。 | — | 命令行参数优先级最高 |
7.4 配置刷新(@RefreshScope)
| 方法/配置项 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
@RefreshScope | 类或 Bean 注解 | 标记该 Bean 支持动态刷新。 | @Component @RefreshScope public class UserService { } | 仅适用于原型(prototype)作用域 |
/actuator/refresh 端点 | 触发配置刷新 | 通知客户端重新加载配置。 | POST http://client/actuator/refresh | 返回更新的配置键列表 |
@ConfigurationProperties | 与 @RefreshScope 结合使用 | 实现配置类的动态刷新。 | @ConfigurationProperties("user") @RefreshScope public class UserProperties { } | 推荐方式 |
| 刷新粒度 | 默认刷新所有 @RefreshScope Bean | 控制刷新范围。 | — | 无法精确到单个属性 |
| 自定义刷新监听 | 实现 RefreshScopeRefreshedEvent 监听器 | 刷新后执行自定义逻辑。 | @EventListener public void handle(RefreshScopeRefreshedEvent event) { ... } | 用于清理缓存等操作 |
| 配置未更新原因 | 检查属性是否在远程配置中 | 排查刷新无效问题。 | 对比本地与远程配置 | 确保属性名拼写一致 |
7.5 高可用与安全配置
| 配置项/方案 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| Config Server 集群 | 部署多个 Config Server 实例 | 避免单点故障。 | 使用 Nginx 或 LoadBalancer 转发请求 | 客户端可配置多个 uri |
| Git 仓库高可用 | 使用高可用 Git 服务(如 GitHub、GitLab HA) | 保证配置存储可靠。 | — | 避免本地单点存储 |
| 对称加密(symmetric) | 使用密钥加密敏感配置。 | 防止密码明文存储。 | encrypt.key: mykey,在配置中使用 {cipher} 开头 | 所有节点需共享密钥 |
| 非对称加密(RSA) | 使用公钥加密,私钥解密。 | 提升安全性,密钥更易管理。 | key-store: location: classpath:keystore.jks password: storepass alias: mykey | 推荐生产环境使用 |
/encrypt 与 /decrypt 端点 | 加解密 REST 接口 | 生成加密配置值。 | POST /encrypt body="password" → {cipher}AQE... | 需启用 endpoints |
| 安全访问 Config Server | 配置 Spring Security 保护端点。 | 防止未授权访问配置。 | security.user.name: user security.user.password: pass | 生产环境必须启用 |
| 使用 Vault 替代 Git | HashiCorp Vault 作为安全配置后端。 | 实现动态密钥、审计日志等高级功能。 | spring.cloud.config.server.vault.host: vault.example.com | 更安全但运维复杂 |
第八章:消息驱动微服务(Spring Cloud Stream)
8.1 消息中间件集成概述
| 概念名称 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| 消息中间件 | 解耦生产者与消费者,异步传递消息。 | 实现事件驱动架构,提升系统响应性。 | Kafka、RabbitMQ、RocketMQ | 根据场景选择 |
| Binder 抽象层 | Spring Cloud Stream 的核心,屏蔽中间件差异。 | 实现应用与消息中间件解耦。 | 通过更换 Binder 依赖切换中间件 | 开发者无需关注底层协议 |
| 发布/订阅模式 | 一个消息可被多个消费者消费。 | 实现事件广播。 | 使用 Topic(Kafka)或 Exchange(RabbitMQ) | 消费组决定消费方式 |
| 消息持久化 | 消息存储在中间件中,确保不丢失。 | 支持离线消费与重试。 | 配置持久化队列或日志保留 | 避免消息丢失 |
| 消费者组(Consumer Group) | 同一组内消费者竞争消费同一条消息。 | 实现负载均衡。 | group: user-service-group | 必须设置避免重复消费 |
| 分区(Partition) | 消息按 Key 分布到不同分区。 | 实现有序消费与负载均衡。 | partition-key-expression: payload.id | 需合理设计 Key |
8.2 Stream 编程模型(Source、Sink、Processor)
| 组件 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| Source | 消息生产者,向通道发送消息。 | 定义输出通道。 | public interface UserSource { @Output("user-out") MessageChannel output(); } | 使用 @EnableBinding(Source.class) |
| Sink | 消息消费者,从通道接收消息。 | 定义输入通道。 | public interface OrderSink { @Input("order-in") SubscribableChannel input(); } | 使用 @EnableBinding(Sink.class) |
| Processor | 同时具备输入和输出通道。 | 实现消息转换或路由。 | public interface TransformProcessor { @Input("input") SubscribableChannel input(); @Output("output") MessageChannel output(); } | 用于中间处理服务 |
@EnableBinding | 绑定接口到物理消息中间件。 | 激活通道连接。 | @EnableBinding(Sink.class) | Spring Cloud Stream 3.x 后推荐函数式编程 |
@Input / @Output | 定义输入或输出通道。 | 声明通道名称与类型。 | @Input("myChannel") SubscribableChannel myInput(); | 通道名用于配置绑定 |
| 函数式编程(推荐) | 使用 java.util.function.Function 等接口 | 替代 @EnableBinding,更简洁。 | @Bean public Consumer<String> logConsumer() { return System.out::println; } | Spring Cloud Stream 3.x 默认模式 |
8.3 使用 Kafka 或 RabbitMQ 作为 Binder
| 配置项 | 语法(application.yml) | 用途 | 代码示例 | 注意事项 |
|---|
spring.cloud.stream.bindings.<channel>.destination | 指定消息目标(Topic/Exchange) | 决定消息发送到哪个主题。 | bindings: user-out: destination: user-events | 必须设置 |
spring.cloud.stream.bindings.<channel>.group | 消费者组名 | 实现竞争消费。 | bindings: order-in: group: order-service | 避免重复消费 |
spring.cloud.stream.kafka.binder.brokers | Kafka Broker 地址 | 连接 Kafka 集群。 | kafka: binder: brokers: localhost:9092 | 多个用逗号分隔 |
spring.cloud.stream.rabbitmq.binder.addresses | RabbitMQ 地址 | 连接 RabbitMQ 服务器。 | rabbitmq: binder: addresses: localhost:5672 | 支持集群 |
| binder 依赖引入 | Maven 依赖 | 选择具体 Binder 实现。 | Kafka: spring-cloud-starter-stream-kafka,RabbitMQ: spring-cloud-starter-stream-rabbit | 不能同时引入多个 |
autoCreateTopics | 是否自动创建 Topic | 简化开发。 | kafka: binder: auto-create-topics: true | 生产环境建议关闭 |
8.4 自定义消息通道与消息格式
| 配置项/方法 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
| 自定义通道接口 | 定义多个输入/输出通道。 | 支持复杂消息流。 | public interface CustomChannels { @Output("alert-out") MessageChannel alert(); @Input("report-in") SubscribableChannel report(); } | 需在 @EnableBinding 中引用 |
content-type | 指定消息序列化格式。 | 控制消息编解码。 | bindings: user-out: content-type: application/json | 支持 text/plain、application/json 等 |
| 自定义序列化器 | 实现 MessageConverter | 处理特殊数据格式(如 Avro、Protobuf)。 | extends AbstractMessageConverter | 高级用法 |
| 消息头(Headers) | 传递元数据。 | 携带上下文信息(如 traceId)。 | MessageBuilder.withHeader("traceId", "123").build(data) | 不要滥用 |
@StreamListener(旧) | 监听指定通道消息。 | 处理输入消息。 | @StreamListener("input") public void handleMessage(String data) { } | 3.x 推荐使用函数式编程 |
| 函数式处理器 | 使用 Function 接口 | 实现消息转换。 | @Bean public Function<String, String> upperCase() { return String::toUpperCase; } | 更简洁,推荐 |
8.5 消息分区与错误处理
| 功能 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| 分区发送 | 按 key 将消息分发到特定分区。 | 保证同一 key 的消息有序。 | spring.cloud.stream.bindings.output.producer.partition-key-expression: payload.id | 需设置 partition-count |
| 分区消费 | 消费者绑定到特定分区。 | 实现并行处理与有序性。 | partitioned: true | 消费者实例数 ≤ 分区数 |
| 错误通道(errorChannel) | 捕获消息处理异常。 | 实现统一错误处理。 | @ServiceActivator(inputChannel = "input.errors") public void handleError(ErrorMessage error) { } | 避免消息丢失 |
| 死信队列(DLQ) | 处理失败多次的消息。 | 隔离问题消息,便于排查。 | enableDlq: true dlqName: dlq.user-events | Kafka 需手动实现 |
| 重试机制 | 自动重试失败的消息。 | 处理瞬时故障。 | max-attempts: 3 back-off-initial-interval: 1000 | 避免对非幂等操作重试 |
| 手动确认(ack) | 关闭自动确认,手动控制 | 确保消息处理成功后再确认。 | acknowledge-mode: manual | 防止消息丢失 |
第九章:服务链路追踪(Spring Cloud Sleuth + Zipkin)
9.1 分布式追踪原理(Trace、Span)
| 概念名称 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| Trace(调用链) | 代表一个完整的请求生命周期,从入口服务到所有依赖服务的调用路径。 | 标识一次完整请求的全局唯一标识。 | TraceId: abc123def456 | 所有相关 Span 共享同一 TraceId |
| Span(跨度) | 代表调用链中的一个基本工作单元,如一次方法调用或一次 HTTP 请求。 | 记录操作的开始时间、耗时、标签等。 | SpanId: xyz789 | 每个 Span 有唯一 SpanId |
| Span ID | 当前操作的唯一标识。 | 区分调用链中的不同操作。 | 自动生成 | 通常为 64 位十六进制字符串 |
| Parent Span ID | 当前 Span 的父操作标识。 | 构建调用层级关系。 | 调用下游服务时设置 | 根 Span 无 Parent |
| Annotation(注解) | 记录 Span 内的关键事件,如 cs(Client Send)、sr(Server Receive)等。 | 标记时间点,用于计算延迟。 | cs: 客户端发起请求时间 | 用于计算网络延迟 |
| Baggage | 跨服务传递的上下文信息(如用户 ID、租户 ID)。 | 实现业务上下文透传。 | baggage.tenant-id=tenant1 | 不用于追踪逻辑,但可携带业务数据 |
9.2 Sleuth 集成与日志埋点
| 配置项/方法 | 语法(application.yml) | 用途 | 代码示例 | 注意事项 |
|---|
spring.sleuth.enabled | 启用或禁用 Sleuth | 控制是否生成追踪信息。 | sleuth: enabled: true | 默认启用 |
| 日志格式增强 | 在日志中自动添加 TraceId 和 SpanId | 快速关联分布式日志。 | %clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr([${spring.application.name:-},%X{traceId:-},%X{spanId:-}]){yellow} %clr(${PID:-}){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx} | 需配置日志模板 |
@NewSpan 注解 | 手动创建新的 Span | 为特定方法或代码块添加追踪。 | @NewSpan public void businessMethod() { ... } | 可指定 spanName |
@ContinueSpan 注解 | 继续使用现有 Span | 在异步或跨线程场景中延续追踪上下文。 | @ContinueSpan public void asyncTask() { ... } | 需确保上下文传递 |
| 自定义标签(Tag) | 为 Span 添加业务相关标签。 | 增强追踪数据的可读性与可分析性。 | tracing.currentSpan().tag("user.id", "123"); | 推荐用于关键业务维度 |
| MDC 自动注入 | Sleuth 自动将 traceId/spanId 写入 MDC | 无需手动处理,日志自动携带追踪信息。 | — | 使用 SLF4J + Logback/Log4j2 时自动生效 |
9.3 Zipkin 服务器搭建
| 方法/配置项 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| 运行 Zipkin Server(Jar) | 使用官方 Jar 包启动 | 快速部署 Zipkin 服务。 | java -jar zipkin-server.jar | 最简单方式 |
| Docker 运行 | 使用 Docker 容器部署 | 环境隔离,便于管理。 | docker run -d -p 9411:9411 openzipkin/zipkin | 推荐开发使用 |
| Spring Boot 集成 | 将 Zipkin 集成到 Spring Boot 项目。 | 自定义 Zipkin 功能。 | 引入 spring-cloud-starter-zipkin | 适用于需要扩展的场景 |
| 存储后端 | Zipkin 支持内存、MySQL、Elasticsearch 等存储。 | 持久化追踪数据。 | STORAGE_TYPE=elasticsearch ES_HOSTS=http://es:9200 | 生产环境推荐 Elasticsearch |
| 接收端点 | Zipkin 暴露的 API 用于接收追踪数据。 | 客户端上报 Span 数据。 | http://zipkin-server:9411/api/v2/spans | POST 方式发送 JSON |
| 依赖服务 | Zipkin 可分析服务间调用依赖。 | 生成服务拓扑图。 | 自动分析 Trace 数据 | 需足够调用数据 |
9.4 可视化链路追踪分析
| 功能 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| 链路查询 | 按服务名、TraceId、时间范围查询调用链。 | 定位特定请求的执行路径。 | 在 Zipkin UI 输入 TraceId | 支持模糊匹配 |
| 耗时分析 | 显示每个 Span 的执行时间。 | 识别性能瓶颈。 | 图形化展示时间轴 | 红色表示耗时较长 |
| 服务依赖图 | 自动生成服务间调用关系图。 | 理解系统架构与依赖。 | UI 中 “Dependencies” 标签页 | 实时更新 |
| 错误标记 | 标记包含异常的 Span。 | 快速定位失败请求。 | Span 显示为红色 | 需正确抛出异常 |
| 并行调用识别 | 展示异步或并行执行的 Span。 | 分析并发行为。 | 多个 Span 水平排列 | 有助于优化并发策略 |
| 上下文查看 | 查看 Span 的标签(Tags)和日志(Logs)。 | 排查问题与业务分析。 | 点击 Span 查看详情 | 可添加自定义 Tags |
9.5 追踪采样策略配置
| 配置项 | 语法(application.yml) | 用途 | 代码示例 | 注意事项 |
|---|
spring.sleuth.sampler.probability | 设置采样率(0.0 ~ 1.0) | 控制上报的 Trace 比例。 | sleuth: sampler: probability: 0.1 | 默认 1.0(全量),生产建议 0.01~0.1 |
AlwaysSampler | 始终采样 | 调试时使用。 | — | 高负载下不推荐 |
ProbabilityBasedSampler | 基于概率采样 | 平衡性能与数据完整性。 | 见上例 | 最常用策略 |
RateLimitingSampler | 基于速率限制采样 | 每秒最多采样 N 条 Trace。 | sleuth.sampler.rate: 10 | 控制上报频率 |
| 自定义 Sampler | 实现 Sampler 接口 | 实现复杂采样逻辑(如按用户、路径采样)。 | @Bean public Sampler customSampler() { ... } | 用于精细化控制 |
| 关闭采样 | 不上报任何追踪数据。 | 生产环境临时关闭。 | sleuth.enabled: false | 排查问题时可临时启用 |
第十章:安全与权限控制(Spring Cloud OAuth2)
10.1 OAuth2 协议核心概念
| 概念名称 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| Resource Owner(资源拥有者) | 用户,拥有资源访问权限的主体。 | 授权第三方访问其资源。 | — | 通常是最终用户 |
| Client(客户端) | 请求访问资源的应用(如 Web、App、微服务)。 | 代表用户请求资源。 | 客户端 ID 和密钥 | 需预先注册 |
| Authorization Server(授权服务器) | 负责认证用户并颁发令牌。 | 实现登录、授权流程。 | Spring Security OAuth2 | 核心安全组件 |
| Resource Server(资源服务器) | 存储用户资源并验证令牌的服务。 | 提供受保护的 API。 | 使用 @EnableResourceServer | 验证 JWT 或查询授权服务器 |
| Access Token | 客户端访问资源的凭证(通常为 JWT)。 | 携带权限信息,用于认证。 | Bearer eyJhbGciOiJIUzI1NiJ9... | 有时效性,需刷新 |
| Refresh Token | 用于获取新的 Access Token。 | 延长会话有效期。 | 单独存储,安全性要求高 | 防止泄露 |
| 授权模式 | OAuth2 定义的四种授权方式。 | 适应不同客户端场景。 | 授权码、密码、客户端凭证、隐式 | 微服务常用密码或客户端凭证 |
10.2 搭建授权服务器(Authorization Server)
| 配置项/注解 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
@EnableAuthorizationServer | 启用授权服务器功能。 | 暴露 /oauth/token 等端点。 | @Configuration @EnableAuthorizationServer public class AuthServerConfig extends AuthorizationServerConfigurerAdapter { } | 需继承配置类 |
configure(ClientDetailsServiceConfigurer) | 配置客户端详情。 | 定义哪些客户端可以接入。 | .inMemory() .withClient("client1") .secret("{noop}secret1") .authorizedGrantTypes("password", "refresh_token") .scopes("read", "write") | 生产环境应使用数据库存储 |
configure(AuthorizationServerEndpointsConfigurer) | 配置令牌端点。 | 设置令牌服务、密钥、令牌存储等。 | .tokenServices(tokenServices()) .authenticationManager(authenticationManager) | 支持 JWT 需配置 TokenStore |
TokenStore | 令牌存储策略(内存、Redis、JWT)。 | 管理令牌的生成与验证。 | return new JwtTokenStore(jwtAccessTokenConverter()); | JWT 模式下无状态 |
JwtAccessTokenConverter | 将令牌转换为 JWT 格式。 | 实现无状态令牌验证。 | converter.setSigningKey("my-secret"); | 密钥需安全保管 |
/oauth/token 端点 | 获取 Access Token 的接口。 | 客户端通过用户名密码等获取令牌。 | POST /oauth/token grant_type=password&username=user&password=pass | 需 Basic Auth 认证客户端 |
10.3 资源服务器集成
| 配置项/注解 | 语法 | 用途 | 代码示例 | 注意事项 |
|---|
@EnableResourceServer | 启用资源服务器功能。 | 自动验证请求中的 Access Token。 | @Configuration @EnableResourceServer public class ResourceServerConfig extends ResourceServerConfigurerAdapter { } | 需配置资源 ID 和令牌服务 |
security.oauth2.resource.user-info-uri | 指向用户信息端点(非 JWT 模式)。 | 验证令牌有效性。 | http://auth-server:8080/user | JWT 模式下无需此配置 |
security.oauth2.resource.jwt.key-value | JWT 签名密钥 | 用于验证 JWT 签名。 | my-secret | 必须与授权服务器一致 |
security.oauth2.resource.jwt.key-uri | JWT 公钥获取地址 | 动态获取公钥验证签名。 | http://auth-server:8080/oauth/token_key | 非对称加密时使用 |
| 配置访问控制 | 定义哪些路径需要认证。 | 实现细粒度权限控制。 | .antMatchers("/api/admin/**").hasRole("ADMIN") .antMatchers("/api/user/**").authenticated() | 结合 Spring Security 使用 |
自定义 AuthenticationEntryPoint | 处理未认证请求。 | 返回统一的错误响应。 | 实现 AuthenticationEntryPoint 接口 | 可返回 JSON 错误 |
10.4 JWT 令牌生成与验证
| 方法/配置项 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
JwtAccessTokenConverter | 将 OAuth2 令牌转换为 JWT。 | 实现无状态认证。 | converter.setSigningKey("secret-key"); | 对称加密 |
| 非对称加密(RSA) | 使用私钥签名,公钥验证。 | 提升安全性,密钥更易管理。 | keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair(); | 推荐生产环境使用 |
| 自定义 JWT 内容 | 在令牌中添加额外信息(如用户 ID、角色)。 | 减少查询数据库次数。 | converter.setAccessTokenConverter(myConverter); | 实现 AccessTokenConverter |
| JWT 解析 | 在资源服务器解析 JWT 内容。 | 获取用户信息与权限。 | Jwts.parser().setSigningKey(key).parseClaimsJws(token); | 需处理异常 |
| 令牌过期处理 | 验证 JWT 是否过期。 | 保证安全性。 | 自动由 JWT 库处理 | 响应 401 状态码 |
| 刷新令牌(Refresh Token) | 使用 Refresh Token 获取新 Access Token。 | 延长用户会话。 | grant_type=refresh_token&refresh_token=xxx | Refresh Token 需安全存储 |
10.5 微服务间安全调用
| 方法/策略 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| 客户端凭证模式(Client Credentials) | 服务间调用使用客户端 ID 和密钥获取令牌。 | 实现服务到服务的认证。 | grant_type=client_credentials | 适用于后台服务调用 |
| 传递原始用户令牌 | 调用链中传递用户的 Access Token。 | 实现用户上下文透传(SSO)。 | Feign 拦截器中添加 Authorization: Bearer {token} | 需处理令牌过期 |
| 服务间 JWT 验证 | 每个微服务独立验证 JWT。 | 实现无状态、高可用认证。 | 配置 JwtAccessTokenConverter | 避免频繁调用授权服务器 |
OAuth2RestTemplate / WebClient | 支持携带令牌的 HTTP 客户端。 | 简化安全调用。 | public OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext context, OAuth2ProtectedResourceDetails details) | WebClient 更推荐 |
| 权限传播 | 在 JWT 中包含权限信息(authorities)。 | 下游服务可基于权限进行控制。 | new OAuth2Request(null, "client", null, true, scopes, null, null, null, authorities) | 避免权限爆炸 |
| 安全头过滤 | 网关剥离敏感头,仅传递必要信息。 | 防止客户端伪造令牌。 | Gateway 中使用过滤器 | 提升整体安全性 |
第十一章:服务总线(Spring Cloud Bus)
11.1 消息总线作用与原理
| 概念名称 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| 消息总线(Bus) | 基于消息中间件(如 RabbitMQ、Kafka)的广播通信机制。 | 实现微服务实例间的轻量级、广播式通信。 | — | 类似”事件总线” |
| 事件驱动 | 通过发布/订阅模式传播事件。 | 解耦服务,实现异步通知。 | ApplicationEvent | Spring 事件模型扩展 |
| 中间件依赖 | 使用 RabbitMQ 或 Kafka 作为底层消息代理。 | 提供可靠的消息传递。 | spring-cloud-starter-bus-amqp / spring-cloud-starter-bus-kafka | 必须引入对应 Binder |
| 全局广播 | 向所有连接到总线的服务实例发送消息。 | 实现批量操作(如刷新配置)。 | POST /actuator/bus-refresh | 影响所有实例 |
| 节点寻址 | 可定向发送到特定实例(如 /bus/refresh?destination=service-user:**:8080)。 | 精准控制更新范围。 | 支持 serviceId + 端口匹配 | 需实例注册信息准确 |
| 实例 ID(instanceId) | 每个服务实例的唯一标识。 | 区分不同节点,用于寻址。 | 自动生成或通过 spring.cloud.client.instance-id 设置 | 格式通常为 ${spring.application.name}:${server.port} |
11.2 Bus 与 Config 集成实现配置刷新
| 配置项/端点 | 语法(application.yml) | 用途 | 代码示例 | 注意事项 |
|---|
spring.cloud.bus.enabled | 启用 Bus 功能 | 开启消息总线支持。 | cloud: bus: enabled: true | 默认启用 |
/actuator/bus-refresh | 总线刷新端点 | 触发所有实例的配置刷新。 | POST http://any-service/actuator/bus-refresh | 只需调用任意一个实例 |
与 @RefreshScope 结合 | 标记可刷新的 Bean | 配置变更后重新加载。 | @RefreshScope 注解类 | 仅支持该注解的 Bean |
| 局部刷新 | 定向刷新特定服务或实例。 | 减少影响范围。 | /bus-refresh?destination=service-user:** | 使用 destination 参数 |
| 自动刷新流程 | Config Server 接收 Git webhook → 发送 RefreshRemoteApplicationEvent → 所有 Client 监听并刷新 | 实现自动化配置更新。 | GitHub Webhook → /monitor | 需启用 spring-cloud-config-monitor |
spring.cloud.config.server.monitor.github-webhook-token | 验证 GitHub Webhook 请求 | 提高安全性。 | 设置 token 并在 GitHub 配置 | 防止伪造请求 |
11.3 自定义事件广播
| 方法/组件 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| 自定义事件类 | 继承 RemoteApplicationEvent | 定义业务事件类型。 | public class CustomEvent extends RemoteApplicationEvent { ... } | 必须有无参构造函数 |
| 事件发布 | 使用 ApplicationEventPublisher 发布事件。 | 主动触发广播。 | publisher.publishEvent(new CustomEvent(this, "service-a", "custom-dest")); | 指定 originService 和 destination |
| 事件监听 | 使用 @EventListener 监听自定义事件。 | 接收并处理广播事件。 | @EventListener public void handleCustomEvent(CustomEvent event) { ... } | 方法参数必须匹配事件类型 |
| 事件序列化 | 事件对象需可序列化(implements Serializable) | 通过消息中间件传输。 | implements Serializable | 字段应尽量简单 |
| 事件过滤 | 通过 destination 控制接收范围。 | 实现精准投递。 | 构造事件时设置 destination="service-b:**" | 支持通配符 |
| 异步处理 | 事件处理逻辑不应阻塞主线程。 | 保证系统响应性。 | 使用 @Async 或线程池 | 避免影响其他监听器 |
11.4 Bus 安全与监控
| 配置项/方案 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| 端点安全控制 | 保护 /bus-refresh 等敏感端点。 | 防止未授权访问。 | management.security.enabled=true security.user.name=admin security.user.password=pass | 生产环境必须启用 |
| 消息加密 | 对总线消息内容加密。 | 防止敏感信息泄露。 | 使用中间件层加密(如 RabbitMQ TLS)或自定义序列化器 | 复杂度较高,按需使用 |
| 访问白名单 | 限制可触发刷新的 IP 或服务。 | 增强安全性。 | 自定义 Filter 拦截 /bus-refresh | 结合 Spring Security |
| Actuator 监控 | 暴露 Bus 相关健康状态。 | 查看连接状态。 | GET /actuator/health | 显示 bus 组件状态 |
| 消息队列监控 | 监控 RabbitMQ/Kafka 队列积压、消费者状态。 | 排查通信问题。 | RabbitMQ Management Plugin | 及时发现消息堆积 |
| 日志审计 | 记录事件发布与接收日志。 | 便于问题追踪与审计。 | 在监听器中添加日志输出 | 包含事件类型、来源、时间 |
第十二章:微服务部署与运维
12.1 Docker 打包 Spring Cloud 应用
| 方法/文件 | 说明 | 用途 | 代码示例 | 注意事项 |
|---|
| Dockerfile | 定义镜像构建过程。 | 将应用打包为容器镜像。 | FROM openjdk:8-jre-alpine COPY app.jar /app.jar ENTRYPOINT ["java", "-jar", "/app.jar"] | 推荐使用瘦镜像(alpine) |
| 多阶段构建 | 在构建阶段编译,运行阶段只包含运行时依赖。 | 减小镜像体积。 | FROM maven AS builder COPY . . RUN mvn package FROM openjdk:8-jre-alpine COPY --from=builder target/app.jar /app.jar | 适用于源码构建场景 |
.dockerignore | 忽略不必要的文件。 | 加快构建,减小镜像。 | target/ .git Dockerfile README.md | 避免将本地文件打入镜像 |
| 镜像标签(tag) | 为镜像打上版本标签。 | 版本管理与部署追踪。 | docker build -t user-service:v1.0 . | 结合 CI/CD 使用 |
| 环境变量注入 | 运行时传入配置。 | 实现环境差异化。 | docker run -e "SPRING_PROFILES_ACTIVE=prod" user-service | 优于硬编码配置 |
| 健康检查指令 | 定义容器健康检查。 | 被编排工具用于判断实例状态。 | HEALTHCHECK --interval=30s --timeout=3s --start-period=5s CMD curl -f http://localhost:8080/actuator/health | 必须定义 |
12.2 使用 Docker Compose 编排微服务
| 配置项/命令 | 语法(docker-compose.yml) | 用途 | 代码示例 | 注意事项 |
|---|
services | 定义多个服务实例。 | 声明微服务组件。 | services: user-service: image: user-service:v1 ports: - "8081:8080" | 每个服务一个条目 |
depends_on | 定义服务启动顺序。 | 确保依赖服务先启动。 | depends_on: - config-server | 仅控制启动顺序,不等待就绪 |
networks | 定义网络,实现服务间通信。 | 隔离不同项目网络。 | networks: microservice-net: driver: bridge | 推荐使用自定义网络,并在服务中指定 networks: [microservice-net] |
environment | 设置环境变量。 | 传入配置参数。 | environment: - SPRING_CLOUD_CONFIG_URI=http://config-server:8888 | 替代配置文件 |
volumes | 挂载数据卷。 | 持久化数据或共享配置。 | ./config:/config | 适用于配置文件或日志 |
docker-compose up/down | 启动/停止所有服务。 | 一键部署与清理。 | docker-compose up -d | -d 表示后台运行 |
scale | 水平扩展服务实例。 | 模拟集群环境。 | docker-compose up -d --scale user-service=3 | 测试负载均衡 |
12.3 Kubernetes 部署微服务集群
| K8s 资源 | 说明 | 用途 | 代码示例(片段) | 注意事项 |
|---|
| Pod | 最小调度单元,包含一个或多个容器。 | 运行微服务实例。 | containers: - name: user-service image: user-service:v1 | 临时性,可能被重建 |
| Deployment | 管理 Pod 的副本集与更新策略。 | 实现无状态服务的部署与扩缩容。 | replicas: 3 strategy: RollingUpdate | 支持滚动更新 |
| Service | 为 Pod 提供稳定的网络访问入口。 | 实现服务发现与负载均衡。 | type: ClusterIP ports: - port: 80 targetPort: 8080 | ClusterIP 为内部访问 |
| Ingress | 对外暴露 HTTP/HTTPS 服务。 | 实现统一网关入口与路径路由。 | rules: - host: api.example.com http: paths: - path: /user backend: user-svc | 需 Ingress Controller |
| ConfigMap | 存储非敏感配置数据。 | 注入环境变量或挂载为文件。 | data: application.yml: server.port: 8080 | — |
| Secret | 存储敏感信息(密码、密钥)。 | 安全地管理凭证。 | data: password: base64-encoded-value | Base64 编码,非加密 |
| Helm Chart | Kubernetes 应用包管理工具。 | 简化复杂应用的部署与版本管理。 | helm install my-app ./chart | 推荐用于生产环境 |
12.4 监控与日志收集方案
| 方案/工具 | 说明 | 用途 | 集成方式 | 注意事项 |
|---|
| Prometheus | 开源监控系统,拉取指标数据。 | 收集微服务 Metrics(CPU、内存、HTTP 耗时等)。 | 引入 micrometer-registry-prometheus,暴露 /actuator/prometheus | 需配置 scrape job |
| Grafana | 可视化仪表盘,展示监控数据。 | 图形化分析系统性能。 | 连接 Prometheus 数据源,创建 Dashboard | 支持告警 |
| ELK Stack(Elasticsearch, Logstash, Kibana) | 日志收集、存储与可视化方案。 | 集中分析分布式日志。 | 应用输出 JSON 日志 → Logstash 收集 → ES 存储 → Kibana 查询 | 资源消耗较大 |
| EFK Stack(Fluentd 替代 Logstash) | 更轻量的日志方案。 | 适用于 Kubernetes 环境。 | Fluentd DaemonSet 收集容器日志 | Kubernetes 常用组合 |
| Micrometer | 应用指标采集门面库。 | 统一接入不同监控系统。 | @Timed 注解方法,自动记录耗时 | Spring Boot Actuator 内置 |
| 分布式追踪集成 | 将 Sleuth + Zipkin 数据上报。 | 关联跨服务调用链。 | 配置 spring.zipkin.base-url | 与监控系统互补 |
12.5 健康检查与弹性伸缩
| 功能/配置 | 说明 | 用途 | 代码示例/配置 | 注意事项 |
|---|
/actuator/health | Spring Boot 健康检查端点 | 报告应用运行状态。 | 默认返回 { "status": "UP" } | 可自定义 HealthIndicator |
健康指示器(HealthIndicator) | 自定义健康检查逻辑。 | 检查数据库、缓存等依赖状态。 | @Component public class DbHealthIndicator implements HealthIndicator { ... } | 影响整体 UP/DOWN 状态 |
| Kubernetes Liveness Probe | 存活探针,检测容器是否存活。 | 不健康则重启容器。 | livenessProbe: httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 | 避免过于频繁 |
| Kubernetes Readiness Probe | 就绪探针,检测是否可接收流量。 | 不就绪则从 Service 中剔除。 | 同上,但用于 readinessProbe | 滚动更新时关键 |
| Horizontal Pod Autoscaler (HPA) | 水平 Pod 自动扩缩器。 | 根据 CPU/内存或自定义指标自动伸缩实例数。 | metrics: - type: Resource resource: name: cpu targetAverageUtilization: 50 | 需 Metrics Server |
| 基于自定义指标伸缩 | 使用 Prometheus 等外部指标。 | 实现业务维度扩缩容(如 QPS)。 | 需配置 Adapter(如 Prometheus Adapter) | 复杂但更智能 |
| 弹性策略设计 | 定义扩缩容阈值、冷却时间等。 | 避免震荡扩缩。 | minReplicas: 2 maxReplicas: 10 downscaleStabilization: 300s | 结合业务高峰调整 |