Hystrix 实现降级、熔断与隔离的代码案例

130 阅读1分钟

一、环境准备

1. 添加依赖

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

2. 启用 Hystrix

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

二、降级(Fallback)

1. 代码示例

@Service
public class UserService {

    @Autowired
    private RestTemplate restTemplate;

    // 定义降级方法
    @HystrixCommand(fallbackMethod = "getUserFallback")
    public String getUser(Long id) {
        return restTemplate.getForObject("http://user-service/user/" + id, String.class);
    }

    // 降级逻辑
    public String getUserFallback(Long id) {
        return "降级结果:用户服务不可用";
    }
}

2. 测试与结果

调用请求

GET http://localhost:8080/user/1  

正常返回

用户信息:1  

模拟服务宕机后调用

GET http://localhost:8080/user/1  

返回降级结果

降级结果:用户服务不可用  

三、熔断(Circuit Breaker)

1. 配置熔断规则

hystrix:
  command:
    default:
      circuitBreaker:
        requestVolumeThreshold: 5     # 触发熔断的最小请求数
        errorThresholdPercentage: 50  # 错误率阈值(50%)
        sleepWindowInMilliseconds: 10000  # 熔断后休眠时间(10秒)

2. 代码示例

@HystrixCommand(fallbackMethod = "getUserFallback")
public String getUser(Long id) {
    if (id % 2 == 0) {  // 模拟偶发故障
        throw new RuntimeException("服务异常");
    }
    return "用户信息:" + id;
}

3. 测试与结果

连续调用 6 次失败请求(id=2)

GET http://localhost:8080/user/2  

返回结果

降级结果:用户服务不可用  

熔断触发后调用正常请求(id=1)

GET http://localhost:8080/user/1  

返回结果

降级结果:用户服务不可用  

等待 10 秒后恢复

GET http://localhost:8080/user/1  

正常返回

用户信息:1  

四、隔离(Isolation)

1. 线程池隔离

代码配置

@HystrixCommand(
    fallbackMethod = "getUserFallback",
    threadPoolKey = "userThreadPool",
    threadPoolProperties = {
        @HystrixProperty(name = "coreSize", value = "10"),   // 核心线程数
        @HystrixProperty(name = "maxQueueSize", value = "20") // 队列容量
    }
)
public String getUser(Long id) { ... }

2. 信号量隔离

代码配置

@HystrixCommand(
    fallbackMethod = "getUserFallback",
    commandProperties = {
        @HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE"),
        @HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests", value = "10")
    }
)
public String getUser(Long id) { ... }