4. Hystrix 实战入门:搭建 Hystrix 项目、@HystrixCommand 注解、配置降级方法

好,咱们开始动手了。这一章我带你从零搭建一个 Hystrix 项目,把核心注解 @HystrixCommand 用起来,再配上降级方法。说白了,就是让你知道熔断器在代码里到底长什么样。

4.1 搭建一个最简单的 Hystrix 项目

我个人习惯用 Spring Boot 来集成 Hystrix,因为省事。你不需要自己搞一堆配置,Spring Cloud 已经把路铺好了。

先加依赖。在 pom.xml 里引入 spring-cloud-starter-netflix-hystrix:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    <version>2.2.10.RELEASE</version>
</dependency>

然后在启动类上加 @EnableCircuitBreaker 注解。嗯,这里要注意,这个注解就是开启熔断器的开关。

@SpringBootApplication
@EnableCircuitBreaker
public class HystrixDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(HystrixDemoApplication.class, args);
    }
}

搞定。项目就能跑了。是不是很简单?

小提示: 如果你用的是 Spring Cloud 2020 之后的版本,Hystrix 已经进入维护模式。但学原理,用它依然是最好的选择。

4.2 @HystrixCommand 注解——熔断的开关

这个注解是 Hystrix 的灵魂。你把它加在哪个方法上,哪个方法就拥有了熔断能力。

我举个例子。假设你有个查询用户信息的服务,调的是远程接口:

@Service
public class UserService {

    @HystrixCommand
    public String getUserInfo(Long userId) {
        // 模拟远程调用,可能会超时或报错
        return restTemplate.getForObject(
            "http://user-service/user/" + userId, String.class);
    }
}

就这么简单?对,就这么简单。但光加注解还不够,你得告诉 Hystrix:出错了怎么办?这就引出了降级方法。

4.3 配置降级方法——兜底方案

降级方法,说白了就是备胎。主方法挂了,备胎顶上。

配置方式有两种:fallbackMethoddefaultFallback。我建议你优先用 fallbackMethod,因为更精确。

@HystrixCommand(fallbackMethod = "getUserInfoFallback")
public String getUserInfo(Long userId) {
    // 可能抛异常
    if (userId == null) {
        throw new RuntimeException("参数异常");
    }
    return "真实用户数据";
}

public String getUserInfoFallback(Long userId) {
    // 降级逻辑:返回缓存或默认值
    return "降级用户数据 - userId: " + userId;
}

注意,降级方法的参数列表必须和原方法一致。返回值类型也要一样。这是硬性要求。

避坑指南: 我曾经犯过一个错——降级方法写在另一个类里,结果死活不生效。后来才发现,fallbackMethod 默认只在同一个类中查找。如果你非要写在别的类里,得用 @HystrixCommand(fallbackMethod = "xxx", commandKey = "yyy") 配合 @Component 注入,但说实话,不推荐这么干,太绕了。

4.4 降级方法的执行时机

你可能会问:什么时候会触发降级?我总结一下,主要有三种情况:

  • 超时: 默认 1 秒没返回,就降级
  • 异常: 方法里抛了未捕获的异常
  • 熔断器打开: 错误率超过阈值,直接走降级

你看,降级方法不是只处理异常,它是个全方位的兜底方案。

4.5 实战:一个完整的例子

咱们写个完整的 Controller 看看效果:

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/user/{id}")
    public String getUser(@PathVariable Long id) {
        return userService.getUserInfo(id);
    }
}

启动项目,访问 /user/1,正常返回。访问 /user/0(假设 0 会触发异常),返回降级数据。

你可以在控制台看到 Hystrix 的日志输出,比如线程池信息、执行时间等。这些信息在调试时很有用。

核心要点:
  • @HystrixCommand 是熔断的入口
  • 降级方法必须和原方法签名一致
  • 降级触发条件:超时、异常、熔断器打开

4.6 我踩过的坑

最后分享两个我实际项目中遇到的坑:

  1. 降级方法里又调远程服务: 有一次我图省事,在降级方法里又调了另一个远程接口。结果那个接口也超时了,降级方法又触发降级,死循环了。记住,降级方法里不要做任何可能失败的操作。
  2. 忽略异常类型: 默认所有异常都触发降级。但有些异常你不想降级,比如参数校验异常。可以用 ignoreExceptions 属性排除:@HystrixCommand(ignoreExceptions = {IllegalArgumentException.class})

嗯,这一章的内容就到这。你先把项目搭起来,跑通一个降级流程。下一章咱们深入配置参数,看看怎么调优熔断器的行为。