Spring Cloud 学习笔记 —— Resilience4 微服务中基本用法

10.3 Resilience4j 结合微服务

Retry、CircuitBreaker、RateLimiter

10.3.1 Retry

  • (1)创建一个 Spring Boot 项目 resilience4j-2 作为 module,添加 web 、eureka client discovery 依赖在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • (2)手动添加 Resilience4j 依赖
		<dependency>
            <groupId>io.github.resilience4j</groupId>
            <artifactId>resilience4j-spring-boot2</artifactId>
            <version>1.5.0</version>
        </dependency>
  • (3)把原来的 application.properties 文件删除,新建 application.yml 文件来配置 retry 重试,配置注册到 Eureka
resilience4j:
  retry:
    retry-aspect-order: 399 #表示 retry 的优先级,默认高于限流、断路器,数值越小,优先级越高
    backends:
      retryA: # 自定义策略 retryA
        maxRetryAttempts: 5 #重试次数
        waitDuration: 500 #重试等待时间
        exponentialBackoffMultiplier: 1.1 #间隔乘数,第一次 1.1秒,第二次 1.21 秒
        retryExceptions: # 触发重试的异常
          - java.lang.RuntimeException
# 项目名及 eureka 配置
spring:
  application:
    name: resilience4j
server:
  port: 5000
eureka:
  client:
    service-url:
      defaultZone: http://localhost:1111/eureka
  • (4)在 provider 服务中,设置本身会抛异常的接口:
   public String hello(){
       String s = "hello   " + port;
       System.out.println(s);
       int i = 1/0;
       return s;
   }
  • (5)resilience4j-2 服务中,创建 RestTemplate 请求模板 bean对象,创建 HelloService 和 HelloController 类
@SpringBootApplication
public class Resilience4j2Application {

    public static void main(String[] args) {
        SpringApplication.run(Resilience4j2Application.class, args);
    }
    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        return new RestTemplate();
    }
}
@Service
@Retry(name="retryA")//表示使用的重试策略
public class HelloService {
    @Autowired
    RestTemplate restTemplate;
    public String hello(){
        String s = restTemplate.getForObject("http://provider/hello", String.class);
        return s;
    }
}
@RestController
public class HelloController {
    @Autowired
    HelloService helloService;
    @GetMapping("/hello")
    public String hello(){
       return helloService.hello();
    }
}

在 HelloService 中的 @Retry(name = "retryA")注解的属性 retryA是在 application.yml中配置自定义的策略名;

  • (6)启动 Eureka 服务端、provider 服务和 resilience4j-2 服务,访问 http://localhost:5000/hello 地址:
    在这里插入图片描述
    在这里插入图片描述
    前端报错
    -(7)查看 provider 控制台日志,看接口中被访问情况:
    在这里插入图片描述
    hello 1113 被打印了5次,说明接口被访问5次,就是说 resilience4j-2 的 retry 重试功能起作用了,重试了 5次。

10.3.2 CircuitBreaker 断路器

  • (1)继续在 application.yml中配置断路器
resilience4j:
  retry:
    retry-aspect-order: 399 #表示 retry 的优先级,默认高于限流、断路器,数值越小,优先级越高
    backends:
      retryA: # 自定义策略 retryA
        maxRetryAttempts: 5 #重试次数
        waitDuration: 500 #重试等待时间
        exponentialBackoffMultiplier: 1.1 #间隔乘数,第一次 1.1秒,第二次 1.21 秒
        retryExceptions: # 触发重试的异常
          - java.lang.RuntimeException
  # 断路器配置
  circuitbreaker:
    instances:
      cbA: # 实例自定义名字
        ringBufferSizeInClosedState: 5
        ringBufferSizeInHalfOpenState: 3
        waitInterval: 5000 #断路器从 open 切换到 half open 需要保持的时间间隔
        recordException: # 服务出现异常,就熔断,降级
          - org.springframework.web.client.HttpServerErrorException
    circuit-breaker-aspect-order: 398
# 项目名及 eureka 配置
spring:
  application:
    name: resilience4j
server:
  port: 5000
eureka:
  client:
    service-url:
      defaultZone: http://localhost:1111/eureka
  • (2)在 HelloServie 类上加上 @CircuitBreaker注解,并配置fallbackMethod属性
@Service
@Retry(name="retryA")
@CircuitBreaker(name = "cbA",fallbackMethod = "error")
public class HelloService {
    @Autowired
    RestTemplate restTemplate;
    public String hello(){
            return restTemplate.getForObject("http://provider/hello", String.class);
    }
    public String error(Throwable t){
        return "error";
    }
}

注意 error 方法的参数要加上Throwable参数,否则会报错,继续访问 hello 接口,返回 error ,说明服务降级了在这里插入图片描述

  • 在 provider 中,我们依然能看见 控制台打印 5次 hello 1113,证明 retry 也在起作用
    在这里插入图片描述
  • (3)retry 和 circuitbreker 一起使用
    在 provider 中更改接口,使请求重试在第二次成功,
@RestController
public class HelloController implements IUserService{
    @Value("${server.port}")
    Integer port;
    @Override
    public String hello(){
        String s = "hello   " + port;
        System.out.println(s);
        if(port++ != 1114){
        	int i = 1/0;
        }
        return s;
    }
}

然后重启provider ,继续访问 hello 接口:
前端结果成功
在这里插入图片描述
provider 服务控制台日志
在这里插入图片描述
打印了两次,说明 retry 的第二次成功了,服务不进行降级。成功返回了结果 hello 1114

10.3.3 RateLimiter

可以在请求端,也可以在被请求端使用,主要在被请求端使用,保护服务端的接口

  • (1)在 provider 中添加 Resilience4j 依赖
		<dependency>
            <groupId>io.github.resilience4j</groupId>
            <artifactId>resilience4j-spring-boot2</artifactId>
            <version>1.5.0</version>
        </dependency>
  • (2)在 application.properties 中配置限流
# 一个周期有几次请求
resilience4j.ratelimiter.instances.rlA.limit-for-period=2
# 一个周期的刷新时间
resilience4j.ratelimiter.instances.rlA.limit-refresh-period=1s
resilience4j.ratelimiter.instances.rlA.timeout-duration=1s

就是一秒处理两个请求

  • (3)修改 provider 中的 hello 接口,打印时间,方便观察限流效果
    @RateLimiter(name = "rlA")
    public String hello(){
        String s = "hello   " + port;
        System.out.println(new Date());
        return s;
    }

@RateLimiter(name = "rlA")注解的 rlAapplication.properties中配置的自定义限流策略名称。

  • (4)在 resilience4j-2 中修改 HelloService 方法, 多次调用 provider 中的接口
@Service
@Retry(name="retryA")
@CircuitBreaker(name = "cbA",fallbackMethod = "error")
public class HelloService {
    @Autowired
    RestTemplate restTemplate;
    public String hello(){
        for (int i = 0;i < 5;i++){
            String s = restTemplate.getForObject("http://provider/hello", String.class);
        }
        return "success";
    }
    public String error(Throwable t){
        return "error";
    }
}
  • (5)重启 provider 和 resilience4j-2 服务,再次调用 http:///localhost:5000/hello,观察 provider 控制台打印情况:
    在这里插入图片描述
    如果修改 application.properties每秒处理一个请求
# 一秒处理一个请求
resilience4j.ratelimiter.instances.rlA.limit-for-period=1
resilience4j.ratelimiter.instances.rlA.limit-refresh-period=1s
resilience4j.ratelimiter.instances.rlA.timeout-duration=1s

再次查看 provider 的控制台
在这里插入图片描述
一秒处理一个请求也起了作用,这就是限流的简单应用

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值