0%

HystrixCommand 执行原理:从 AOP 拦截到命令执行的全解析

Hystrix 通过@HystrixCommand注解实现对方法的容错增强,其底层依赖 AOP 切面拦截目标方法,封装执行逻辑(如熔断、隔离、降级)。本文结合源码详细解析 HystrixCommand 的执行流程,从注解拦截到命令执行的每一步核心逻辑。

AOP 入口:HystrixCommandAspect

Hystrix 通过HystrixCommandAspect切面类拦截所有标注@HystrixCommand的方法,这是执行流程的起点。

1. 切面定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Aspect
public class HystrixCommandAspect {
// 切点:拦截所有标注@HystrixCommand的方法
@Pointcut("@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand)")
public void hystrixCommandAnnotationPointcut() {}

// 环绕通知:处理拦截到的方法
@Around("hystrixCommandAnnotationPointcut()")
public Object methodsAnnotatedWithHystrixCommand(final ProceedingJoinPoint joinPoint) throws Throwable {
// 1. 解析方法元数据(注解配置、参数等)
Method method = getMethodFromTarget(joinPoint);
MetaHolder metaHolder = createMetaHolder(joinPoint, method);

// 2. 创建Hystrix命令对象(封装执行逻辑)
HystrixInvokable invokable = HystrixCommandFactory.getInstance().create(metaHolder);

// 3. 执行命令(根据执行类型同步/异步处理)
Object result = executeCommand(invokable, metaHolder);

return result;
}
}
阅读全文 »

@EnableZuulProxy 与 @EnableZuulServer 的区别:Zuul 网关的两种启用方式

在 Zuul 中,@EnableZuulProxy@EnableZuulServer是启用网关功能的两个核心注解,两者的差异主要体现在功能范围内置过滤器上。@EnableZuulProxy@EnableZuulServer的超集,提供了更完整的路由能力(如集成服务发现和负载均衡),而@EnableZuulServer仅包含基础网关功能。

核心差异:功能范围

注解 定位 核心能力 适用场景
@EnableZuulProxy 增强版网关(代理模式) 包含@EnableZuulServer的所有功能,额外支持: - 与服务发现(Eureka 等)集成 - 基于 Ribbon 的负载均衡 - 路由到注册中心的微服务 微服务架构(需动态路由到服务)
@EnableZuulServer 基础版网关(服务器模式) 仅支持静态路由(配置固定 URL)和基础过滤器,不依赖服务发现和 Ribbon 简单路由场景(无服务发现需求)

底层实现:自动配置类的继承关系

Zuul 的自动配置类清晰体现了两者的关系:
ZuulProxyAutoConfiguration 继承 ZuulServerAutoConfiguration,即@EnableZuulProxy包含@EnableZuulServer的所有配置,并额外添加了服务发现和负载均衡相关的 Bean。

阅读全文 »

解决 Spring Cloud Config Server 单点问题:基于服务发现的高可用方案

Spring Cloud Config Server 作为分布式配置中心,若采用单点部署,一旦服务宕机,所有依赖它的客户端将无法获取配置,导致系统故障。通过将 Config Server 注册到服务发现组件(如 Eureka、Nacos),可实现其高可用部署,避免单点风险。

单点问题的根源与解决方案

问题表现

客户端通过固定的uri配置连接 Config Server:

1
2
3
4
spring:
cloud:
config:
uri: http://localhost:7010 # 固定地址,存在单点风险

localhost:7010的 Config Server 宕机后,客户端无法切换到其他实例,导致配置获取失败。

解决方案

利用服务发现机制,将多个 Config Server 实例注册到服务中心,客户端通过服务名而非固定地址访问,实现自动负载均衡和故障转移:

  1. 部署多个 Config Server 实例并注册到服务中心;
  2. 客户端通过服务名从服务中心获取 Config Server 地址;
  3. 客户端与 Config Server 之间通过负载均衡建立连接。

基于 Eureka 的 Config Server 高可用配置

以下以 Eureka 作为服务发现组件,详细说明配置步骤:

阅读全文 »

Spring Cloud Config 配置存储机制:从本地文件到 Git 仓库

Spring Cloud Config 作为分布式配置中心,支持多种配置存储方式,核心通过 EnvironmentRepository 接口实现配置的读取与管理。不同的存储方式对应不同的 EnvironmentRepository 实现,其中最常用的是本地文件存储Git 仓库存储

EnvironmentRepository:配置存储的核心接口

EnvironmentRepository 是 Spring Cloud Config 中配置存储的顶层接口,定义了获取配置的核心方法:

1
2
3
4
public interface EnvironmentRepository {
// 根据应用名、环境、分支获取配置
Environment findOne(String application, String profile, String label);
}

Environment 类是配置数据的载体,包含以下核心字段:

  • name:应用名(对应 spring.application.name);
  • profiles:环境(如 devprod);
  • label:分支(如 Git 分支 master);
  • version:配置版本(如 Git 提交哈希);
  • propertySources:配置键值对集合。

基于本地文件的配置存储(NativeEnvironmentRepository)

当配置中心需要从本地文件系统读取配置时,使用 NativeEnvironmentRepository 实现,适用于开发环境或无版本控制需求的场景。

启用本地文件存储

需通过 spring.profiles.active=native 激活本地存储模式:

阅读全文 »

RestTemplate 拦截器(ClientHttpRequestInterceptor)详解与实践

RestTemplate 的拦截器机制允许我们在 HTTP 请求发送前和响应返回后进行自定义处理,非常适合实现日志记录、请求头添加、认证信息附加等横切关注点功能。

ClientHttpRequestInterceptor 核心原理

ClientHttpRequestInterceptor 是 RestTemplate 的拦截器接口,其核心方法 intercept 会在请求执行前后被调用:

1
2
3
4
5
6
7
public interface ClientHttpRequestInterceptor {
ClientHttpResponse intercept(
HttpRequest request,
byte[] body,
ClientHttpRequestExecution execution
) throws IOException;
}
  • request:即将发送的 HTTP 请求对象,可修改请求头、请求方法等
  • body:请求体内容
  • execution:执行器,调用其 execute 方法继续请求链的执行

拦截器的执行流程如下:

阅读全文 »