一、背景描述
由於Hystrix官方已經停止更新,Spring 官網推薦使用Resilience4j作爲服務的熔斷保護中間件,可見Resilience4j的重要性。
爲了探究Resilience4j實現服務熔斷功能, 我們選用了 consul 作爲註冊中心,啓動了一個服務端(waiter),驗證其服務端限流、併發控制熔斷。我們在極端的時間內訪問較多次數指定接口,觀察接口是否會進行熔斷處理。 consul 啓動及運行狀態監控,不在這裏描述, 我們默認 consul 已經正常運行。
本地安裝運行consul 參考:https://jingyan.baidu.com/article/ca41422f732f961eaf99ed5f.html
在RateLimiter中有兩種使用方式:基於註解,或熔斷對象注入兩種方式,下面會分別進行演示。
二、代碼演示
2.1 pom主要依賴
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR1</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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>0.14.1</version>
</dependency>
2.2 配置文件
application.properties
#0表示服務器隨機端口
server.port=0
#consul 地址
spring.cloud.consul.host=localhost
#consul 端口
spring.cloud.consul.port=8500
spring.cloud.consul.discovery.prefer-ip-address=true
#限流熔斷組annotation策略設置如下:
#限制連續請求5次
resilience4j.ratelimiter.limiters.annotation.limit-for-period=5
#30s刷新統計值
resilience4j.ratelimiter.limiters.annotation.limit-refresh-period-in-millis=30000
#5s超時
resilience4j.ratelimiter.limiters.annotation.timeout-in-millis=5000
#actuator 訂閱endpoint
resilience4j.ratelimiter.limiters.annotation.subscribe-for-events=true
#Metrics endpoint監控指標
resilience4j.ratelimiter.limiters.annotation.register-health-indicator=true
#限流熔斷組registry策略設置如下:
#限制連續請求3次
resilience4j.ratelimiter.limiters.registry.limit-for-period=3
#30s刷新統計值
resilience4j.ratelimiter.limiters.registry.limit-refresh-period-in-millis=30000
#5s超時
resilience4j.ratelimiter.limiters.registry.timeout-in-millis=1000
#actuator 訂閱endpoint
resilience4j.ratelimiter.limiters.registry.subscribe-for-events=true
#Metrics endpoint監控指標
resilience4j.ratelimiter.limiters.registry.register-health-indicator=true
bootstrap.properties
#服務名稱
spring.application.name=waiter-service
2.3 代碼
1)AnnotationController 基於註解實現
@RestController
@RequestMapping("/annotation")
@Slf4j
@RateLimiter(name = "annotation")
public class AnnotationController {
@PostMapping("/value")
public Object gotoValue(){
String result = "hello ! this is return annotation ratelimiter";
return result ;
}
2)RegistryController 基於注入類方式實現
@RestController
@RequestMapping("registry")
@Slf4j
public class RegistryController {
private RateLimiter rateLimiter;
public RegistryController(RateLimiterRegistry rateLimiterRegistry) {
rateLimiter = rateLimiterRegistry.rateLimiter("registry");
}
@RequestMapping("/resut")
public Object gotoRegistry(HttpServletRequest request){
String resut = null;
try {
resut = rateLimiter.executeSupplier(() -> "hello ! this is return registry ratelimiter ! haha! ");
} catch(RequestNotPermitted e) {
log.warn("Request Not Permitted! {}", e.getMessage());
}
return resut;
}
}
三、熔斷結果演示
- 基於註解熔斷情況
接口:http://localhost:8080/annotation/value
步驟:連續請接口5次
正常返回
返回報錯
後端報錯
- 基於註冊熔斷器方式熔斷情況
接口:http://localhost:8080/registry/resut
步驟:連續請接口3次
正常返回
返回報錯(空)
後端報錯
- 熔斷監控
可以通過actuator 查看當前服務熔斷情況
請求熔斷情況: http://localhost:8080/actuator/ratelimiters
有哪些熔斷器策略:http://localhost:8080/actuator/ratelimiters