请求重试
创建springboot项目,选择web、eureka-client依赖,创建完成后添加resilience4j依赖
<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>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>1.2.0</version>
<exclusions>
<exclusion>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-circuitbreaker</artifactId>
</exclusion>
<exclusion>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-ratelimiter</artifactId>
</exclusion>
<exclusion>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-bulkhead</artifactId>
</exclusion>
<exclusion>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-timelimiter</artifactId>
</exclusion>
</exclusions>
</dependency>
注意:resilience4j-spring-boot2中包含了resilience4j中所有的功能,未配置的功能无法正常使用,所以要将其他组件先从依赖中排除。
新建yml文件,配置retry,并将该服务注册到erueka
resilience4j:
retry:
retry-aspect-order: 399 # 表示retry优先级,一般retry优先级高于限流和断路器
backends:
retryA:
maxRetryAttempts: 5 # 重试次数
waitDuration: 500 # 重试等待时间
exponentialBackoffMultipliter: 1.1 # 间隔乘数
retryException:
- java.lang.RuntimeException
spring:
application:
name: resilience4j
server:
port: 5000
eureka:
client:
service-url:
defaultZone: http://localhost:1111/eureka
新建Service,调用provider中的接口,声明使用重试策略的名称
@Service
@Retry(name = "retryA")
public class HelloService {
@Autowired
RestTemplate restTemplate;
public String hello(){
return restTemplate.getForObject("http://localhost:1113/hello",String.class);
}
}
最后编写测试接口,进行测试,可以看到方法共执行了五次。
circuitbreaker
现在依赖中删除对circuitbreaker组件的排除
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>1.2.0</version>
<exclusions>
<exclusion>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-ratelimiter</artifactId>
</exclusion>
<exclusion>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-bulkhead</artifactId>
</exclusion>
<exclusion>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-timelimiter</artifactId>
</exclusion>
</exclusions>
</dependency>
在yml中配置circuitbreaker实例
circuitbreaker:
instances:
cbA:
ringBufferSizeInClosedState: 5
ringBufferSizeInHalfOpenState: 3
waitInterval: 5000
recordExceptions:
- org.springframework.web.client.HttpServerErrorException
在service中添加服务降级的方法,并在@CircuitBreaker注解中声明断路器的策略和服务降级返回的方法。
@Service
@CircuitBreaker(name = "cbA",fallbackMethod = "error")
public class HelloService {
@Autowired
RestTemplate restTemplate;
public String hello(){
return restTemplate.getForObject("http://localhost:1113/hello",String.class);
}
public String error(Throwable t){
return "error";
}
}
访问测试接口可以看到页面返回到error,服务降级成功。
RateLimiter
RateLimiter作为一个限流工具,主要用于服务端,用来保护接口
在provider中添加resilience4j依赖
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot2</artifactId>
<version>1.2.0</version>
<exclusions>
<exclusion>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-circuitbreaker</artifactId>
</exclusion>
<exclusion>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-bulkhead</artifactId>
</exclusion>
<exclusion>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-timelimiter</artifactId>
</exclusion>
</exclusions>
</dependency>
在application.properties中配置RateLimiter
resilience4j.ratelimiter.limiters..rlA.limit-for-period=1
resilience4j.ratelimiter.limiters.rlA.limit-refresh-period=1s
resilience4j.ratelimiter.limiters..rlA.timeout-duration=1s
为了查看效果,在provider的接口中打印每个请求处理时间。通过@RateLimiter(name = "rlA")标记该接口限流,限流策略为rlA
@Override
@RateLimiter(name = "rlA")
public String hello(){
String s = "hello cloud" + port;
System.out.println(new Date());
return s;
}
在resilience4j模块的接口中多次发送请求进行测试
public String hello(){
for (int i = 0; i < 3; i++) {
restTemplate.getForObject("http://localhost:1113/hello",String.class);
}
return "success";
}
可以看到限流生效
image。
网友评论