spring-retry
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
// springboot啟動類
@EnableRetry
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
// 實作類正常方法
// openTimeout時間範圍内失敗maxAttempts次數後,熔斷打開resetTimeout時長
@CircuitBreaker(maxAttempts = 3, openTimeout = 3000L, resetTimeout = 5000L )
public String normalMethod(String param) {
log.info("======== normalMethod ======== " + param);
if (true) {
throw new RuntimeException("方法異常");
}
return param;
}
// 降級方法
@Recover
public String recoverMethod(Throwable t, String param) {
log.info("======== recoverMethod ======== " + param);
return param;
}
日志如下, 觀察日志發現并沒有half-open半開過程,熔斷關閉後會每次重試maxAttempts次請求。還有一點,spring-retry不支援線程池、信号量隔離。
2019-12-20 18:43:30.552: ======== normalMethod ======== testParam
2019-12-20 18:43:30.553: ======== recoverMethod ======== testParam
2019-12-20 18:43:30.813: ======== normalMethod ======== testParam
2019-12-20 18:43:30.813: ======== recoverMethod ======== testParam
2019-12-20 18:43:31.456: ======== normalMethod ======== testParam
2019-12-20 18:43:31.456: ======== recoverMethod ======== testParam
2019-12-20 18:43:31.785: ======== recoverMethod ======== testParam
2019-12-20 18:43:33.589: ======== recoverMethod ======== testParam
2019-12-20 18:43:45.059: ======== normalMethod ======== testParam
2019-12-20 18:43:45.059: ======== recoverMethod ======== testParam
2019-12-20 18:43:45.579: ======== normalMethod ======== testParam
2019-12-20 18:43:45.579: ======== recoverMethod ======== testParam
2019-12-20 18:43:47.294: ======== normalMethod ======== testParam
2019-12-20 18:43:47.294: ======== recoverMethod ======== testParam
2019-12-20 18:43:47.757: ======== recoverMethod ======== testParam
2019-12-20 18:43:50.242: ======== recoverMethod ======== testParam
hystrix
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.5.18</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>1.5.18</version>
</dependency>
// springboot啟動類省略
// 由于沒有使用自動裝配,需要自己定義相關Bean
@Configuration
public class HystrixConfig {
@Bean
public HystrixCommandAspect hystrixCommandAspect() {
return new HystrixCommandAspect();
}
@Bean
public HystrixShutdownHook hystrixShutdownHook() {
return new HystrixShutdownHook();
}
private class HystrixShutdownHook implements DisposableBean {
@Override
public void destroy() throws Exception {
// Just call Hystrix to reset thread pool etc.
Hystrix.reset();
}
}
}
// 預設熔斷規則是10秒鐘内,20次請求,存在50%失敗就熔斷5秒鐘時間
@HystrixCommand(fallbackMethod = "fallbackMethod",
commandProperties = {@HystrixProperty(name = "execution.isolation.strategy", value = "SEMAPHORE"),
@HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests", value = "200"),
@HystrixProperty(name = "fallback.isolation.semaphore.maxConcurrentRequests", value = "200")})
public String normalMethod(String param) {
log.info("======== normalMethod ======== " + param);
if (true) {
throw new RuntimeException("方法異常");
}
return param;
}
public String fallbackMethod(String param) {
log.info("======== fallbackMethod ======== " + param);
return param;
}
日志如下, 觀察日志發現在熔斷開啟5秒過後存在half-open半開過程,會有一次正常請求發送。
2019-12-20 18:45:01.079: ======== normalMethod ======== testParam
2019-12-20 18:45:01.085: ======== fallbackMethod ======== testParam
2019-12-20 18:45:01.322: ======== normalMethod ======== testParam
2019-12-20 18:45:01.323: ======== fallbackMethod ======== testParam
2019-12-20 18:45:01.954: ======== normalMethod ======== testParam
2019-12-20 18:45:01.954: ======== fallbackMethod ======== testParam
2019-12-20 18:45:02.532: ======== normalMethod ======== testParam
2019-12-20 18:45:02.533: ======== fallbackMethod ======== testParam
2019-12-20 18:45:03.063: ======== normalMethod ======== testParam
2019-12-20 18:45:03.063: ======== fallbackMethod ======== testParam
2019-12-20 18:45:03.505: ======== normalMethod ======== testParam
2019-12-20 18:45:03.506: ======== fallbackMethod ======== testParam
2019-12-20 18:45:03.972: ======== normalMethod ======== testParam
2019-12-20 18:45:03.972: ======== fallbackMethod ======== testParam
2019-12-20 18:45:04.414: ======== normalMethod ======== testParam
2019-12-20 18:45:04.414: ======== fallbackMethod ======== testParam
2019-12-20 18:45:04.865: ======== normalMethod ======== testParam
2019-12-20 18:45:04.866: ======== fallbackMethod ======== testParam
2019-12-20 18:45:05.625: ======== normalMethod ======== testParam
2019-12-20 18:45:05.625: ======== fallbackMethod ======== testParam
2019-12-20 18:45:06.253: ======== normalMethod ======== testParam
2019-12-20 18:45:06.253: ======== fallbackMethod ======== testParam
2019-12-20 18:45:06.806: ======== normalMethod ======== testParam
2019-12-20 18:45:06.806: ======== fallbackMethod ======== testParam
2019-12-20 18:45:07.377: ======== normalMethod ======== testParam
2019-12-20 18:45:07.378: ======== fallbackMethod ======== testParam
2019-12-20 18:45:07.938: ======== normalMethod ======== testParam
2019-12-20 18:45:07.938: ======== fallbackMethod ======== testParam
2019-12-20 18:45:08.335: ======== normalMethod ======== testParam
2019-12-20 18:45:08.336: ======== fallbackMethod ======== testParam
2019-12-20 18:45:08.843: ======== normalMethod ======== testParam
2019-12-20 18:45:08.843: ======== fallbackMethod ======== testParam
2019-12-20 18:45:09.404: ======== normalMethod ======== testParam
2019-12-20 18:45:09.404: ======== fallbackMethod ======== testParam
2019-12-20 18:45:09.940: ======== normalMethod ======== testParam
2019-12-20 18:45:09.940: ======== fallbackMethod ======== testParam
2019-12-20 18:45:10.466: ======== normalMethod ======== testParam
2019-12-20 18:45:10.466: ======== fallbackMethod ======== testParam
2019-12-20 18:45:10.889: ======== normalMethod ======== testParam
2019-12-20 18:45:10.889: ======== fallbackMethod ======== testParam
2019-12-20 18:45:11.438: ======== fallbackMethod ======== testParam
2019-12-20 18:45:11.946: ======== fallbackMethod ======== testParam
2019-12-20 18:45:12.414: ======== fallbackMethod ======== testParam
2019-12-20 18:45:12.971: ======== fallbackMethod ======== testParam
2019-12-20 18:45:16.774: ======== normalMethod ======== testParam
2019-12-20 18:45:16.774: ======== fallbackMethod ======== testParam
2019-12-20 18:45:17.245: ======== fallbackMethod ======== testParam
2019-12-20 18:45:17.718: ======== fallbackMethod ======== testParam
2019-12-20 18:45:18.189: ======== fallbackMethod ======== testParam
2019-12-20 18:45:18.622: ======== fallbackMethod ======== testParam
2019-12-20 18:45:33.752: ======== normalMethod ======== testParam
2019-12-20 18:45:33.752: ======== fallbackMethod ======== testParam
2019-12-20 18:45:34.669: ======== fallbackMethod ======== testParam
2019-12-20 18:45:35.354: ======== fallbackMethod ======== testParam
2019-12-20 18:45:35.968: ======== fallbackMethod ======== testParam
2019-12-20 18:45:36.592: ======== fallbackMethod ======== testParam