hystrix基础操作
1基础demo
- 完成父模块
- 完成eureka子模块
- 完成服务提供者子模块
- 完成服务消费者子模块
1.完成父模块
新建springboot项目,删除src文件夹
导入maven依赖
<properties>
<java.version>1.8</java.version>
<spring.cloud-version>Hoxton.SR3</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>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2.完成eureka子模块
新建子模块eureka
导入maven依赖
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> </dependencies>
编写application.yml配置文件
server: port: 7001 spring: application: name: cs-eureka eureka: instance: # 地址 通常是域名 hostname: localhost client: service-url: # 客户端与EurekaServer的交互地址,如果是集群,需要多个地址 defaultZone: http://localhost:7001/eureka/ register-with-eureka: false # 是不是将自己注册进eureka 默认 true fetch-registry: false # 自己就是服务,不需要从eurekaServer获取服务信息,默认true
编写主启动类
@SpringBootApplication @EnableEurekaServer //开启服务 public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); } }
3.完成服务提供者子模块
新建子模块provider-hystrix
导入maven依赖
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies>
编写application配置文件
spring: application: name: provider-hystrix server: port: 8001 eureka: client: # eureka服务端的路劲 service-url: defaultZone: http://localhost:7001/eureka/ # 如果不想将改服务注册进注册中心,一定要写成false register-with-eureka: true fetch-registry: true
编写主启动类
@SpringBootApplication @EnableEurekaClient @EnableHystrix public class HystrixApplication { public static void main(String[] args) { SpringApplication.run(HystrixApplication.class,args); } }
编写HystrixController.java
降级的方法写在提供者或消费者中都可以,我写到消费者中
@RestController @RequestMapping("/provider") public class HystrixController { @GetMapping("/hystrix/ok") public String providerHystrixOk(){ return Thread.currentThread().getName() + "providerHystrixOk"; } @GetMapping("/hystrix/timeout") public String providerHystrixTimeOut(){ int time=3; //休眠3秒 try { TimeUnit.SECONDS.sleep(time); } catch (InterruptedException e) { e.printStackTrace(); } return Thread.currentThread().getName() + "providerHystrixTimeOut,耗时" + time; } }
3.完成服务消费者子模块
导入maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</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-netflix-eureka-client</artifactId>
</dependency>
</dependencies>
编写application.yml文件
server:
port: 9001
eureka:
client:
# eureka服务端的路径,这个就是eureka模块设置的地址
service-url:
defaultZone: http://localhost:7001/eureka/
# 是不是将自己注册进eureka 默认 true,所以这里可以省略不写
register-with-eureka: true
ribbon:
ReadTimeout: 5000 #处理请求的超时时间,默认5秒
ConnectTimeout: 5000 #连接建立的超时时间,默认5秒
feign:
hystrix:
enabled: true
编写主启动类
@SpringBootApplication @EnableEurekaClient @EnableFeignClients @EnableHystrix public class ConsumerHystrixApplication { public static void main(String[] args) { SpringApplication.run(ConsumerHystrixApplication.class,args); } }
ProviderHystrixService.java
@FeignClient(value = "PROVIDER-HYSTRIX")//value是provide注册到eaurke的名字 @Service public interface ProviderHystrixService { @GetMapping("/provider/hystrix/ok") String providerHystrixOk(); @GetMapping("/provider/hystrix/timeout") String providerHystrixTimeOut(); }
ConsumerHystrixController.java
@RestController @RequestMapping("/consumer") public class ConsumerHystrixController { private final ProviderHystrixService providerHystrixService; public ConsumerHystrixController(ProviderHystrixService providerHystrixService) { this.providerHystrixService = providerHystrixService; } @GetMapping("/hystrix/ok") public String consumerHystrixTimeOk(){ return providerHystrixService.providerHystrixOk(); }
/*
fallbackMethod:降级的方法名
name="execution.isolation.thread.timeoutInMilliseconds"熔断的规则
我选的是响应超时时间 value="2000" 2秒
* */
@GetMapping("/hystrix/timeout")
@HystrixCommand(fallbackMethod = "providerHystrixTimeOutHandler",commandProperties = {
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "2000")
})
public String consumerHystrixTimeOut(){
return providerHystrixService.providerHystrixTimeOut();
}
//降级的方法 public String providerHystrixTimeOutHandler(){ return "哎呀,出错了,服务器丢失"; } }
启动eureka
启动provider-hystrix
启动consumer-hystrix
运行截图:
访问正常的方法
访问超时的方法(规则在2s内有响应,程序休眠3秒)
2.基础demo优化
- 每一个方法都需要有降级一个的方法
解决:使用全局服务降级的方法
修改ConsumerHystrixController.java
@RestController @RequestMapping("/consumer") @DefaultProperties(defaultFallback = "global_FallbackMethod") public class ConsumerHystrixController { private final ProviderHystrixService providerHystrixService; public ConsumerHystrixController(ProviderHystrixService providerHystrixService) { this.providerHystrixService = providerHystrixService; } @GetMapping("/hystrix/ok") public String consumerHystrixTimeOk(){ return providerHystrixService.providerHystrixOk(); } @GetMapping("/hystrix/timeout") @HystrixCommand public String consumerHystrixTimeOut(){ //模拟异常 int a=10/0; return providerHystrixService.providerHystrixTimeOut(); } public String global_FallbackMethod(){ return "Global异常处理信息,请稍后重试"; } }
运行截图:
-
兜底的方法写到controller中了,耦合了,能不能分离处理
我们采用了OpenFeign实现负载均衡,我们在调用Controller层方法的时候都是去到对应的Service层方法,找到要调用服务的服务名然后去实现调用的,所以我们可以在声明一个类去继承service接口,然后这个类专门对service里面的方法实现Fallback。而且OpenFeign加在Service接口上的注解@FeignClient提供了对Fallback的支持
解决:使用通配服务降级有两种方式
fallbackFactory和fallback
区别在于:fallbackFactory除了可以降级hystrix的异常,其他异常也可以,fallback不行
使用fallback:
新建ProviderHystrixServiceFallBack.java
1.继承ProviderHystrixService接口
2.注意添加@Compoent注解
@Component public class ProviderHystrixServiceFallback implements FallbackFactory<ProviderHystrixService> { private final String MSG="系统异常,正在拿程序员小哥祭天"; @Override public ProviderHystrixService create(Throwable throwable) { return new ProviderHystrixService() { @Override public String providerHystrixOk() { return throwable.getMessage() + MSG; } @Override public String providerHystrixTimeOut() { return MSG; } }; } }
修改ProviderHystrixService.java
@FeignClient(value = "PROVIDER-HYSTRIX", fallback = ProviderHystrixServiceFallback.class) @Service public interface ProviderHystrixService { @GetMapping("/provider/hystrix/ok") String providerHystrixOk(); @GetMapping("/provider/hystrix/timeout") String providerHystrixTimeOut(); }
修改ConsumerHystrixController.java
@RestController @RequestMapping("/consumer") //@DefaultProperties(defaultFallback = "global_FallbackMethod") public class ConsumerHystrixController { private final ProviderHystrixService providerHystrixService; public ConsumerHystrixController(ProviderHystrixService providerHystrixService) { this.providerHystrixService = providerHystrixService; } @GetMapping("/hystrix/ok") public String consumerHystrixTimeOk(){ //模拟异常 int a=10/0; return providerHystrixService.providerHystrixOk(); } @GetMapping("/hystrix/timeout") public String consumerHystrixTimeOut(){ return providerHystrixService.providerHystrixTimeOut(); } }
运行截图:
无法降级其他异常
可以降级超时异常
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)