本文目录导读:

我来提供一个完整的Hystrix使用案例,包括服务降级、熔断、线程隔离等核心功能。
项目基础配置
Maven依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.10.RELEASE</version>
</dependency>
<!-- 如果需要Feign配合使用 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
启动类配置
@SpringBootApplication
@EnableHystrix // 或者使用 @EnableCircuitBreaker
@EnableFeignClients
public class HystrixApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixApplication.class, args);
}
}
基础降级案例
服务提供者(UserService)
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
// 模拟数据库查询
return User.builder()
.id(id)
.name("张三")
.email("zhangsan@example.com")
.build();
}
}
服务消费者(使用Hystrix降级)
@RestController
@RequestMapping("/api/client")
@Slf4j
public class UserClientController {
@Autowired
private UserServiceClient userServiceClient;
/**
* 使用注解方式实现降级
*/
@GetMapping("/user/{id}")
@HystrixCommand(
fallbackMethod = "getUserFallback",
commandKey = "getUserCommand",
groupKey = "userServiceGroup",
threadPoolKey = "userServiceThreadPool"
)
public User getUser(@PathVariable Long id) {
// 调用远程服务
User user = userServiceClient.getUserById(id);
if (user == null) {
throw new RuntimeException("用户不存在");
}
return user;
}
/**
* 降级方法
*/
public User getUserFallback(Long id, Throwable throwable) {
log.error("获取用户信息失败,id: {}, 原因: {}", id, throwable.getMessage());
return User.builder()
.id(id)
.name("默认用户")
.email("default@example.com")
.remark("降级返回的默认用户")
.build();
}
/**
* 使用编程式方式实现降级
*/
@GetMapping("/programmatic/user/{id}")
public User getUserProgrammatic(@PathVariable Long id) {
User user = executeWithHystrix(() -> userServiceClient.getUserById(id));
return user != null ? user : getDefaultUser(id);
}
private User executeWithHystrix(Supplier<User> action) {
return new HystrixCommand<User>(
com.netflix.hystrix.HystrixCommand.Setter
.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ProgrammaticGroup"))
.andCommandKey(HystrixCommandKey.Factory.asKey("GetUserCommand"))
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("ProgrammaticThreadPool"))
) {
@Override
protected User run() {
return action.get();
}
@Override
protected User getFallback() {
return getDefaultUser(0L);
}
}.execute();
}
}
进阶功能案例
自定义注解与配置
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface HystrixRateLimit {
String fallback() default "";
int timeoutInMs() default 1000;
int threadPoolSize() default 10;
}
配置化降级
@RestController
@RequestMapping("/api/advanced")
@Slf4j
public class AdvancedHystrixController {
@Autowired
private PaymentService paymentService;
/**
* 配置化的降级处理
*/
@GetMapping("/payment/create")
@HystrixCommand(
fallbackMethod = "createPaymentFallback",
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000"),
@HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"),
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "5000"),
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50")
},
threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "10"),
@HystrixProperty(name = "maxQueueSize", value = "100")
},
ignoreExceptions = {IllegalArgumentException.class}
)
public PaymentResult createPayment(@RequestBody PaymentRequest request) {
// 调用支付服务
return paymentService.pay(request);
}
public PaymentResult createPaymentFallback(PaymentRequest request, Throwable throwable) {
log.error("支付服务降级,原因:{}", throwable.getMessage());
return PaymentResult.builder()
.code("PAY_FALLBACK")
.message("支付服务暂时不可用,请稍后重试")
.fallbackTime(LocalDateTime.now())
.build();
}
/**
* 批量模式降级
*/
@PostMapping("/batch/payments")
@HystrixCommand(
fallbackMethod = "batchPaymentFallback",
commandProperties = {
@HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE"),
@HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests", value = "20"),
@HystrixProperty(name = "fallback.isolation.semaphore.maxConcurrentRequests", value = "10")
}
)
public List<PaymentResult> batchPayments(@RequestBody List<PaymentRequest> requests) {
return requests.stream()
.map(paymentService::pay)
.collect(Collectors.toList());
}
}
服务间调用降级
@Component
@FeignClient(
name = "order-service",
fallbackFactory = OrderServiceFallbackFactory.class
)
public interface OrderServiceClient {
@GetMapping("/api/orders/{orderId}")
OrderResponse getOrderById(@PathVariable String orderId);
@GetMapping("/api/orders/user/{userId}")
List<OrderResponse> getUserOrders(@PathVariable Long userId);
@PostMapping("/api/orders")
OrderResponse createOrder(@RequestBody CreateOrderRequest request);
}
@Component
@Slf4j
public class OrderServiceFallbackFactory implements FallbackFactory<OrderServiceClient> {
@Override
public OrderServiceClient create(Throwable cause) {
return new OrderServiceClient() {
@Override
public OrderResponse getOrderById(String orderId) {
log.error("获取订单失败,orderId: {}, 原因: {}", orderId, cause.getMessage());
return OrderResponse.builder()
.orderId(orderId)
.status("FALLBACK")
.errorMsg("订单服务不可用")
.build();
}
@Override
public List<OrderResponse> getUserOrders(Long userId) {
return Collections.singletonList(
OrderResponse.builder()
.userId(userId)
.status("FALLBACK")
.errorMsg("订单服务不可用")
.build()
);
}
@Override
public OrderResponse createOrder(CreateOrderRequest request) {
return OrderResponse.builder()
.orderId("FALLBACK")
.status("FAILED")
.errorMsg("订单服务不可用")
.build();
}
};
}
}
自定义Hystrix配置
配置文件
# application.yml
hystrix:
command:
default:
execution:
isolation:
strategy: THREAD
thread:
timeoutInMilliseconds: 3000
timeoutEnabled: true
semaphore:
maxConcurrentRequests: 10
circuitBreaker:
enabled: true
requestVolumeThreshold: 20
sleepWindowInMilliseconds: 5000
errorThresholdPercentage: 50
forceOpen: false
forceClosed: false
metrics:
rollingStats:
timeInMilliseconds: 10000
numBuckets: 10
fallback:
enabled: true
isolation:
semaphore:
maxConcurrentRequests: 10
getUserCommand:
execution:
isolation:
thread:
timeoutInMilliseconds: 2000
circuitBreaker:
requestVolumeThreshold: 10
sleepWindowInMilliseconds: 10000
errorThresholdPercentage: 40
threadpool:
default:
coreSize: 10
maxQueueSize: 100
queueSizeRejectionThreshold: 10
keepAliveTimeMinutes: 1
allowMaximumSizeToDivergeFromCoreSize: true
maximumSize: 20
userServiceThreadPool:
coreSize: 5
maxQueueSize: 50
监控配置
@Configuration
public class HystrixMetricsConfig {
@Bean
public HystrixMetricsPoller hystrixMetricsPoller() {
return new HystrixMetricsPoller();
}
@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
请求合并案例
@Service
public class RequestCollapsingService {
@HystrixCollapser(
scope = com.netflix.hystrix.HystrixCollapser.Scope.GLOBAL,
batchMethod = "batchGetUsers",
collapserProperties = {
@HystrixProperty(name = "timerDelayInMilliseconds", value = "100"),
@HystrixProperty(name = "maxRequestsInBatch", value = "100")
}
)
public User getUserInfo(Long userId) {
return new User(); // 这个方法的返回值会被批量方法覆盖
}
@HystrixCommand(commandKey = "batchGetUsers")
public List<User> batchGetUsers(List<Long> userIds) {
// 批量调用用户服务
return userService.batchGetUsers(userIds);
}
}
实际业务应用场景
电商系统降级案例
@RestController
@RequestMapping("/api/mall")
@Slf4j
public class MallController {
@Autowired
private ProductServiceClient productService;
@Autowired
private InventoryServiceClient inventoryService;
@Autowired
private PriceServiceClient priceService;
/**
* 商品详情页(多服务降级)
*/
@GetMapping("/product/{id}")
@HystrixCommand(
fallbackMethod = "getProductDetailFallback",
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "5000"),
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "20")
}
)
public ProductDetailVO getProductDetail(@PathVariable Long id) {
// 并行调用多个服务
CompletableFuture<Product> productFuture =
CompletableFuture.supplyAsync(() -> getProductWithFallback(id));
CompletableFuture<Inventory> inventoryFuture =
CompletableFuture.supplyAsync(() -> getInventoryWithFallback(id));
CompletableFuture<Price> priceFuture =
CompletableFuture.supplyAsync(() -> getPriceWithFallback(id));
// 等待所有服务响应
CompletableFuture.allOf(productFuture, inventoryFuture, priceFuture).join();
return ProductDetailVO.builder()
.product(productFuture.join())
.inventory(inventoryFuture.join())
.price(priceFuture.join())
.status("SUCCESS")
.build();
}
private Product getProductWithFallback(Long id) {
try {
return productService.getProduct(id);
} catch (Exception e) {
return Product.builder()
.id(id)
.name("商品信息获取失败")
.fallback(true)
.build();
}
}
/**
* 秒杀系统降级
*/
@PostMapping("/seckill/{skuId}")
@HystrixCommand(
fallbackMethod = "seckillFallback",
threadPoolKey = "seckillThreadPool",
threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "5"),
@HystrixProperty(name = "maxQueueSize", value = "50")
},
commandProperties = {
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000")
}
)
public SeckillResult seckill(@PathVariable Long skuId, @RequestParam Long userId) {
// 秒杀逻辑
if (userId == null) {
throw new IllegalArgumentException("非法参数");
}
return seckillService.doSeckill(skuId, userId);
}
public SeckillResult seckillFallback(Long skuId, Long userId, Throwable throwable) {
log.warn("秒杀服务降级,skuId: {}, userId: {}, 原因: {}", skuId, userId, throwable.getMessage());
return SeckillResult.builder()
.code(500)
.message("活动太火爆,请稍后重试")
.fallback(true)
.build();
}
}
测试案例
@SpringBootTest
@RunWith(SpringRunner.class)
public class HystrixTest {
@Autowired
private UserClientController userClientController;
@Test
public void testFallback() {
// 测试降级
User user = userClientController.getUser(999L);
assertNotNull(user);
assertEquals("默认用户", user.getName());
assertTrue(user.isFallback());
}
@Test
public void testCircuitBreaker() {
// 测试熔断器
for (int i = 0; i < 50; i++) {
try {
userClientController.getUser(1000L + i);
} catch (Exception e) {
// 忽略异常
}
}
// 检查熔断器状态
HystrixCircuitBreaker breaker = HystrixCircuitBreaker.Factory.getInstance(
HystrixCommandKey.Factory.asKey("getUserCommand")
);
assertNotNull(breaker);
assertTrue(breaker.isOpen() || breaker.allowRequest());
}
}
这些案例覆盖了Hystrix的核心功能,包括:
- 基本降级处理
- 自定义配置
- 线程池隔离
- 请求合并
- 熔断器配置
- 监控集成
- 实际业务场景应用
你可以根据具体需求选择合适的实现方式,记得合理配置超时时间和降级策略,避免影响系统性能。