本文目录导读:

我为您提供一个完整的Spring Cloud Hystrix案例,包含服务提供者、服务消费者和熔断降级实现。
项目结构
hystrix-demo
├── pom.xml
├── service-provider
│ ├── pom.xml
│ └── src/main/java/com/example/provider
│ ├── ProviderApplication.java
│ └── controller/UserController.java
└── service-consumer
├── pom.xml
└── src/main/java/com/example/consumer
├── ConsumerApplication.java
├── controller/ConsumerController.java
├── service/UserService.java
└── service/fallback/UserServiceFallback.java
父POM配置 (pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>hystrix-demo</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>service-provider</module>
<module>service-consumer</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.12.RELEASE</version>
<relativePath/>
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR12</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
服务提供者
1 提供者POM (service-provider/pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>hystrix-demo</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>service-provider</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
</project>
2 提供者启动类 (ProviderApplication.java)
package com.example.provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
3 提供者配置 (application.yml)
server:
port: 8081
spring:
application:
name: service-provider
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
4 用户控制器 (UserController.java)
package com.example.provider.controller;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/api/user")
public class UserController {
@GetMapping("/{id}")
public Map<String, Object> getUser(@PathVariable Long id) {
// 模拟正常响应
Map<String, Object> result = new HashMap<>();
result.put("id", id);
result.put("name", "用户" + id);
result.put("age", 20 + id.intValue());
result.put("service", "provider");
return result;
}
@GetMapping("/timeout")
public Map<String, Object> getUserWithTimeout() {
try {
// 模拟超时操作
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
Map<String, Object> result = new HashMap<>();
result.put("status", "success");
result.put("message", "响应时间3秒");
return result;
}
@GetMapping("/error")
public Map<String, Object> getUserWithError() {
// 模拟异常
throw new RuntimeException("服务异常");
}
}
服务消费者(包含Hystrix)
1 消费者POM (service-consumer/pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.example</groupId>
<artifactId>hystrix-demo</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>service-consumer</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>
2 消费者启动类 (ConsumerApplication.java)
package com.example.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableFeignClients
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
3 消费者配置 (application.yml)
server:
port: 8082
spring:
application:
name: service-consumer
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
# Hystrix配置
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 4000
circuitBreaker:
requestVolumeThreshold: 10
errorThresholdPercentage: 50
sleepWindowInMilliseconds: 5000
getUserById:
execution:
isolation:
thread:
timeoutInMilliseconds: 2000
circuitBreaker:
requestVolumeThreshold: 5
errorThresholdPercentage: 50
sleepWindowInMilliseconds: 10000
# Feign开启Hystrix
feign:
hystrix:
enabled: true
4 Feign客户端接口 (UserClient.java)
package com.example.consumer.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.Map;
@FeignClient(name = "service-provider", fallback = UserServiceFallback.class)
public interface UserClient {
@GetMapping("/api/user/{id}")
Map<String, Object> getUserById(@PathVariable("id") Long id);
@GetMapping("/api/user/timeout")
Map<String, Object> getUserWithTimeout();
@GetMapping("/api/user/error")
Map<String, Object> getUserWithError();
}
5 降级处理类 (UserServiceFallback.java)
package com.example.consumer.service.fallback;
import com.example.consumer.service.UserClient;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
public class UserServiceFallback implements UserClient {
@Override
public Map<String, Object> getUserById(Long id) {
Map<String, Object> fallback = new HashMap<>();
fallback.put("status", "fallback");
fallback.put("message", "获取用户信息失败,返回降级数据");
fallback.put("id", id);
fallback.put("name", "降级用户");
fallback.put("service", "fallback");
return fallback;
}
@Override
public Map<String, Object> getUserWithTimeout() {
Map<String, Object> fallback = new HashMap<>();
fallback.put("status", "fallback");
fallback.put("message", "请求超时,已触发降级");
return fallback;
}
@Override
public Map<String, Object> getUserWithError() {
Map<String, Object> fallback = new HashMap<>();
fallback.put("status", "fallback");
fallback.put("message", "服务异常,已触发降级");
return fallback;
}
}
6 服务类 (UserService.java)
package com.example.consumer.service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class UserService {
@Autowired
private UserClient userClient;
/**
* 使用HystrixCommand注解(不用Feign的降级)
*/
@HystrixCommand(fallbackMethod = "getUserByIdFallback",
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000"),
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "50")
})
public Map<String, Object> getUserById(Long id) {
// 使用Feign调用
Map<String, Object> result = userClient.getUserById(id);
return result;
}
/**
* 降级方法
*/
public Map<String, Object> getUserByIdFallback(Long id) {
Map<String, Object> fallback = new HashMap<>();
fallback.put("status", "fallback");
fallback.put("message", "服务调用失败,使用本地降级方法");
fallback.put("id", id);
fallback.put("name", "本地降级");
return fallback;
}
/**
* 测试超时
*/
@HystrixCommand(fallbackMethod = "timeoutFallback")
public Map<String, Object> getUserWithTimeout() {
return userClient.getUserWithTimeout();
}
public Map<String, Object> timeoutFallback() {
Map<String, Object> fallback = new HashMap<>();
fallback.put("status", "fallback");
fallback.put("message", "超时降级");
return fallback;
}
/**
* 测试异常
*/
@HystrixCommand(fallbackMethod = "errorFallback")
public Map<String, Object> getUserWithError() {
return userClient.getUserWithError();
}
public Map<String, Object> errorFallback() {
Map<String, Object> fallback = new HashMap<>();
fallback.put("status", "fallback");
fallback.put("message", "异常降级");
return fallback;
}
/**
* 使用线程池隔离
*/
@HystrixCommand(groupKey = "UserGroup",
commandKey = "GetUserCommand",
threadPoolKey = "UserThreadPool",
threadPoolProperties = {
@HystrixProperty(name = "coreSize", value = "5"),
@HystrixProperty(name = "maxQueueSize", value = "10")
},
fallbackMethod = "getUserByIdFallback")
public Map<String, Object> getUserWithThreadPool(Long id) {
return userClient.getUserById(id);
}
}
7 消费者控制器 (ConsumerController.java)
package com.example.consumer.controller;
import com.example.consumer.service.UserClient;
import com.example.consumer.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
@Autowired
private UserService userService;
@Autowired
private UserClient userClient;
/**
* 通过Service调用(带降级)
*/
@GetMapping("/user/{id}")
public Map<String, Object> getUser(@PathVariable Long id) {
return userService.getUserById(id);
}
/**
* 测试超时场景
*/
@GetMapping("/test/timeout")
public Map<String, Object> testTimeout() {
long start = System.currentTimeMillis();
Map<String, Object> result = userService.getUserWithTimeout();
long end = System.currentTimeMillis();
Map<String, Object> response = new HashMap<>();
response.put("result", result);
response.put("time", (end - start) + "ms");
return response;
}
/**
* 测试异常场景
*/
@GetMapping("/test/error")
public Map<String, Object> testError() {
return userService.getUserWithError();
}
/**
* 测试线程池隔离
*/
@GetMapping("/test/thread-pool/{id}")
public Map<String, Object> testThreadPool(@PathVariable Long id) {
return userService.getUserWithThreadPool(id);
}
/**
* 直接通过Feign调用(使用Feign的降级)
*/
@GetMapping("/direct/user/{id}")
public Map<String, Object> directGetUser(@PathVariable Long id) {
return userClient.getUserById(id);
}
/**
* 健康检查端点
*/
@GetMapping("/health")
public Map<String, Object> health() {
Map<String, Object> health = new HashMap<>();
health.put("status", "UP");
health.put("service", "consumer");
return health;
}
}
测试用例
1 RestTemplate测试类
package com.example.consumer;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.ResponseEntity;
import java.util.Map;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HystrixTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
public void testGetUser() {
ResponseEntity<Map> response = restTemplate.getForEntity(
"/consumer/user/1", Map.class);
System.out.println("Response: " + response.getBody());
}
@Test
public void testTimeout() {
ResponseEntity<Map> response = restTemplate.getForEntity(
"/consumer/test/timeout", Map.class);
System.out.println("Timeout Response: " + response.getBody());
}
@Test
public void testError() {
ResponseEntity<Map> response = restTemplate.getForEntity(
"/consumer/test/error", Map.class);
System.out.println("Error Response: " + response.getBody());
}
}
运行说明
1 启动Eureka服务注册中心
# 需要先启动一个Eureka Server(端口8761)
2 启动服务提供者
cd service-provider mvn spring-boot:run # 访问 http://localhost:8081/api/user/1
3 启动服务消费者
cd service-consumer mvn spring-boot:run # 访问 http://localhost:8082/consumer/user/1
测试场景
- 正常调用:
http://localhost:8082/consumer/user/1 - 超时降级:
http://localhost:8082/consumer/test/timeout(等待3秒后降级) - 异常降级:
http://localhost:8082/consumer/test/error - 线程池隔离:
http://localhost:8082/consumer/test/thread-pool/1 - Feign降级:
http://localhost:8082/consumer/direct/user/1
Hystrix Dashboard监控(可选)
添加监控依赖和配置:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
@SpringBootApplication
@EnableCircuitBreaker
@EnableHystrixDashboard
public class ConsumerApplication {
// ...
}
配置yml:
management:
endpoints:
web:
exposure:
include: hystrix.stream, health, info
这个完整的案例涵盖了:
- 服务提供者和消费者
- Feign集成Hystrix
- HystrixCommand注解方式
- 降级处理
- 超时设置
- 线程池隔离
- 熔断器配置
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播