本文目录导读:

我来为你提供一个Java服务熔断的实操案例,使用Spring Cloud Gateway + Sentinel或Hystrix来实现。
使用Sentinel实现服务熔断(推荐)
环境准备
<!-- pom.xml -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2021.0.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
业务代码示例
// 1. 模拟远程调用服务
@Service
public class UserService {
// 模拟调用远程服务
@SentinelResource(value = "getUserInfo",
fallback = "getUserInfoFallback",
blockHandler = "handleBlock")
public String getUserInfo(Long userId) {
// 模拟远程调用
if (userId == null || userId < 0) {
throw new RuntimeException("参数异常");
}
// 模拟延迟
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "用户信息:" + userId;
}
// 降级处理方法
public String getUserInfoFallback(Long userId, Throwable e) {
return "服务暂时不可用,请稍后重试!错误:" + e.getMessage();
}
// 流控处理方法
public String handleBlock(Long userId, BlockException ex) {
return "请求已被限流,请稍后重试!";
}
}
// 2. Controller层
@RestController
@RequestMapping("/api")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/user/{id}")
public String getUser(@PathVariable Long id) {
return userService.getUserInfo(id);
}
}
熔断配置
# application.yml
spring:
application:
name: sentinel-demo
cloud:
sentinel:
transport:
dashboard: localhost:8080 # Sentinel控制台地址
eager: true
# 或者在代码中配置
@Configuration
public class SentinelConfig {
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
}
熔断规则配置
@Component
public class SentinelRulesConfig {
@PostConstruct
public void initRules() {
// 1. 熔断规则 - 异常比例
List<DegradeRule> degradeRules = new ArrayList<>();
DegradeRule degradeRule = new DegradeRule("getUserInfo")
.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO) // 异常比例
.setCount(0.5) // 异常比例阈值为50%
.setTimeWindow(10) // 熔断时长10秒
.setMinRequestAmount(5) // 触发熔断的最小请求数
.setStatIntervalMs(1000); // 统计时长1秒
degradeRules.add(degradeRule);
DegradeRuleManager.loadRules(degradeRules);
// 2. 熔断规则 - 慢调用比例
List<DegradeRule> slowRules = new ArrayList<>();
DegradeRule slowRule = new DegradeRule("getUserInfo")
.setGrade(RuleConstant.DEGRADE_GRADE_RT) // 慢调用
.setCount(200) // 响应时间超过200ms
.setTimeWindow(10) // 熔断时长10秒
.setMinRequestAmount(10) // 触发熔断的最小请求数
.setSlowRatioThreshold(0.5); // 慢调用比例阈值
slowRules.add(slowRule);
DegradeRuleManager.loadRules(slowRules);
// 3. 流控规则
List<FlowRule> flowRules = new ArrayList<>();
FlowRule flowRule = new FlowRule("getUserInfo")
.setGrade(RuleConstant.FLOW_GRADE_QPS) // QPS限流
.setCount(10) // 阈值10 QPS
.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT);
flowRules.add(flowRule);
FlowRuleManager.loadRules(flowRules);
}
}
使用Hystrix实现服务熔断
环境准备
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
业务代码示例
// 1. 服务类
@Service
public class OrderService {
// 使用Hystrix实现熔断
@HystrixCommand(
fallbackMethod = "getOrderFallback",
commandProperties = {
// 熔断配置
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), // 10秒内请求数
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), // 熔断时长10秒
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50"), // 错误率阈值50%
// 线程池配置
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"), // 超时时间1秒
@HystrixProperty(name = "execution.isolation.strategy", value = "THREAD") // 线程池隔离
},
threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "10"), // 核心线程数
@HystrixProperty(name = "maxQueueSize", value = "100"), // 队列大小
@HystrixProperty(name = "queueSizeRejectionThreshold", value = "50") // 队列拒绝阈值
}
)
public String getOrder(Long orderId) {
// 模拟调用远程服务
if (orderId == null || orderId < 0) {
throw new RuntimeException("订单ID异常");
}
// 模拟延迟
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "订单信息:" + orderId;
}
// 降级方法
public String getOrderFallback(Long orderId, Throwable e) {
return "订单服务不可用,请稍后重试!错误类型:" + e.getClass().getSimpleName();
}
}
// 2. Controller层
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping("/{id}")
public String getOrder(@PathVariable Long id) {
return orderService.getOrder(id);
}
}
启动类配置
@SpringBootApplication
@EnableCircuitBreaker // 或者 @EnableHystrix
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
测试用例
@SpringBootTest
@RunWith(SpringRunner.class)
public class CircuitBreakerTest {
@Autowired
private UserService userService;
@Test
public void testDegrade() throws InterruptedException {
// 模拟大量请求触发熔断
for (int i = 0; i < 100; i++) {
String result = userService.getUserInfo(-1L); // 构造异常请求
System.out.println("请求结果:" + result);
Thread.sleep(100);
}
// 等待熔断恢复
Thread.sleep(12000);
// 再次请求(应该恢复正常)
String result = userService.getUserInfo(1L);
System.out.println("恢复后请求结果:" + result);
}
}
监控与查看
Sentinel控制台
# 下载并启动Sentinel Dashboard java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.5.jar
查看熔断状态
@RestController
public class MonitorController {
@GetMapping("/circuit-breaker/status")
public Map<String, Object> getCircuitBreakerStatus() {
Map<String, Object> status = new HashMap<>();
// Sentinel状态
Set<DegradeRule> degradeRules = DegradeRuleManager.getRules();
status.put("sentinel.degrade.rules", degradeRules);
// Hystrix状态
HystrixCircuitBreaker breaker = HystrixCircuitBreaker.Factory
.getInstance(HystrixCommandKey.Factory.asKey("getUserInfo"));
if (breaker != null) {
status.put("hystrix.isOpen", breaker.isOpen());
status.put("hystrix.allowRequest", breaker.allowRequest());
}
return status;
}
}
最佳实践建议
- 合理设置阈值:根据业务实际情况调整熔断阈值
- 优雅降级:降级方法提供友好的提示信息
- 监控告警:结合Prometheus + Grafana进行可视化监控
- 渐进式恢复:使用半开状态逐步恢复服务
- 缓存兜底:降级时返回缓存数据而不是空数据
这个实战案例涵盖了熔断的核心流程,你可以直接运行测试观察熔断效果。