提示:本文环境截止2023年4月,所涉及框架、JDK、IDEA版本均为相对最新,下文不再赘述。
SpringCloud集成Hystrix关于@EnableHystrix失效问题
环境
Maven依赖:
`
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<druid-version>1.2.16</druid-version>
<mybatis.spring.boot-version>3.0.1</mybatis.spring.boot-version>
<mybatis.plus.boot.starter-version>3.5.3.1</mybatis.plus.boot.starter-version>
<hutool.all-version>5.8.16</hutool.all-version>
<spring.cloud-version>2022.0.2</spring.cloud-version>
<spring.boot-version>3.0.5</spring.boot-version>
<spring.cloud.alibaba-version>2021.0.4.0</spring.cloud.alibaba-version>
<spring.boot.maven.plugin-version>3.0.4</spring.boot.maven.plugin-version>
</properties>
主启动类XXXApplication.java:
@SpringBootApplication
@EnableHystrix
public class HystrixSimpleApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixSimpleApplication.class, args);
}
}
业务类与熔断注解:
@HystrixCommand(fallbackMethod = "simpleHandler")
public String getIdTimeOut(Integer id) {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "getIdTimeOut方法,ID=" + id;
}
public String simpleHandler(Integer id) {
return "网络异常,请稍后再试!ID=" + id;
}
一、问题?
现象:
启动服务器、客户端后发现,并没有走simpleHandler方法(不设置超时时间,Hystrix默认1000毫秒),而是等待3秒后完成。
分析:
此时说明@HystrixCommand注解失效,进而怀疑@EnableHystrix注解可能也失效。
二、源码跟进
1.注解@EnableHystrix
代码如下:
package org.springframework.cloud.netflix.hystrix;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
/**
* Convenience annotation for clients to enable Hystrix circuit breakers (specifically).
* Use this (optionally) in case you want discovery and know for sure that it is Hystrix
* you want. All it does is turn on circuit breakers and let the autoconfiguration find
* the Hystrix classes if they are available (i.e. you need Hystrix on the classpath as
* well).
*
* @author Dave Syer
* @author Spencer Gibb
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@EnableCircuitBreaker
public @interface EnableHystrix {
}
发现问题:EnableCircuitBreaker类没有引入
2.继续Client包跟进
spring-cloud-commons-4.x之后,我们发现关于熔断的描述,Spring已经废弃了@EnableCircuitBreaker注解。
这么说是有根据的,随意的引入spring-cloud-commons-3.x,则会有如下图所示。
/**
* Annotation to enable a CircuitBreaker implementation.
* https://martinfowler.com/bliki/CircuitBreaker.html
* @deprecated as of the 3.0.1 release. Hystrix has been removed from Spring Cloud Netflix
* and it was the only implementation using this annotation.
* @author Spencer Gibb
*/
@Deprecated
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(EnableCircuitBreakerImportSelector.class)
public @interface EnableCircuitBreaker {
}
结论:4.x之后,Hystrix无效,可能正是此导致,因为无法扫描到Hystrix的配置,故导致前述一系列的无效。
Spencer Gibb大哥的意思是,奈飞是唯一使用此注解的实现。
三、解决
引入配置类即可:
@Configuration
public class MyHystrixConfig {
/**
* 用来拦截处理HystrixCommand注解
* @return
*/
@Bean
public HystrixCommandAspect hystrixCommandAspect() {
return new HystrixCommandAspect();
}
}
总结
最新版SpringCloud、Hystrix集成至此告一段落。