Forest Forest
💒 首页
  • v1.5.30
  • v1.5.28
  • 🎄 ForestX
🌰 案例
💖 支持
🛫 更新记录
🧢 开发团队
⚒️ 参与贡献
  • MaxKey - 业界领先的身份管理和认证产品 (opens new window)
  • Snowy - 国内首个国密前后端分离快速开发平台 (opens new window)
  • Eoapi - 一个开源、可拓展的 API 工具平台 (opens new window)
  • Gitee (opens new window)
  • Github (opens new window)
💒 首页
  • v1.5.30
  • v1.5.28
  • 🎄 ForestX
🌰 案例
💖 支持
🛫 更新记录
🧢 开发团队
⚒️ 参与贡献
  • MaxKey - 业界领先的身份管理和认证产品 (opens new window)
  • Snowy - 国内首个国密前后端分离快速开发平台 (opens new window)
  • Eoapi - 一个开源、可拓展的 API 工具平台 (opens new window)
  • Gitee (opens new window)
  • Github (opens new window)
  • 序言

    • 🎁 新手介绍
    • 📖 文档
    • 🌰 使用案例
    • 🕵️‍ 关于作者
    • 👨‍🎓 贡献者列表
  • 入门

    • 🎬 安装配置说明
    • 🏹 Springboot环境安装
    • 📐 Springboot环境配置
    • 🎯 Springboot环境使用
    • 🏹 Spring环境安装
    • 📐 Spring环境配置
    • 🎯 Spring环境使用
    • 🏹 原生Java环境安装
    • 📐 原生Java环境配置
    • 🎯 原生Java环境使用
    • 🧬 编程式接口
  • 配置项

    • 👜 Springboot环境配置项
    • 👝 Spring环境配置项
    • 🎒 原生Java环境配置项
    • 📚 配置优先级/作用域
  • 声明式接口

    • 🧱 构建接口
    • 🍀 请求方法
    • 🚚 请求地址
    • 🎈 URL 参数
    • 🍭 请求头
    • 👔 请求体
    • 🍮 后端框架
    • 🧁 接口注解
    • 📬 接收数据
    • 🍛 数据转换
    • 🍓 成功/失败条件
    • 🍌 重试机制
      • 配置全局重试信息
      • 使用@Retry注解
        • 在方法上挂上@Retry注解
        • 接口上使用@Retry注解
      • 重试器
      • 重试条件
        • 重试流程
        • 使用@Success注解设置重试条件
        • 使用 RetryWhen 接口实现重试条件
      • 拦截器onRetry方法
    • 🥂 重定向
    • 🍔 Gzip解压
    • 🎂 日志管理
    • ⚽ 回调函数
    • 🍟 异步请求
    • 🛡️ HTTPS
    • 🍪 使用Cookie
    • 🛸 使用代理
    • 🍉 上传下载
    • 🚑 异常处理
  • 编程式接口

    • 请求API

      • 🚀 请求对象
      • 🚢 请求属性
      • ✨ 执行请求
      • 🎊 后端框架
      • 🎪 请求类型
      • 🔮 请求地址
      • 🧀 URL 参数
      • 🚅 请求头
      • 🚋 请求体
      • ⚓ 回调函数
      • 🚁 异步请求
      • 🥯 Cookie
      • 🍜 成功/失败条件
      • 🌶️ 重试机制
      • ⛵ 重定向
      • 🛰️ 请求代理
    • 响应API

      • 🌠 响应对象
      • ✒️ 读取数据
      • 🦋 响应状态码
      • 🏥 响应错误处理
      • 🎧 响应头
      • 🥞 Cookie
  • 模板表达式

    • 🍬 Hello World
    • 🍹 配置属性引用
    • 🍖 变量引用
    • 🥃 动态变量绑定
    • 🥗 参数序号引用
    • 🍍 引用对象属性
    • 🥝 调用对象方法
  • 高级特性

    • 🥪 拦截器
    • 🍏 自定义注解
    • 🍇 组合注解
    • 🥑 自定义转换器
  • v1.5.28文档
  • 声明式接口
公子骏
2022-07-01
目录

🍌 重试机制

Forest请求在发送失败的情况下会触发重试机制,重试的次数限制、时间间隔、触发条件全部都可以配置

# 配置全局重试信息

重试属性的全局配置

    # 全局配置下,所有请求的默认重试信息按此配置进行
    
    forest:
        max-retry-count: 3     # 最大请求重试次数,默认为 0 次
        max-retry-interval: 10 # 为最大重试时间间隔, 单位为毫秒,默认为 0 毫秒
    
    1
    2
    3
    4
    5
    # 全局配置下,所有请求的默认重试信息按此配置进行
    
    # 最大请求重试次数,默认为 0 次
    forest.max-retry-count=3
    # 为最大重试时间间隔, 单位为毫秒,默认为 0 毫秒   
    forest.max-retry-interval=10
    
    1
    2
    3
    4
    5
    6
    <!-- retryCount 最大请求重试次数,默认为 0 次 -->
    <!-- maxRetryInterval 最大重试时间间隔, 单位为毫秒,默认为 0 毫秒 -->
    <forest:configuration
        ... ...
        retryCount="3"
        maxRetryInterval="10">
    ... ...
    </forest:configuration>
    
    1
    2
    3
    4
    5
    6
    7
    8
    // 获取全局默认配置对象
    ForestConfiguration configuration = Forest.config();
    // 最大请求重试次数,默认为 0 次
    configuration.setMaxRetryCount(3);
    // 为最大重试时间间隔, 单位为毫秒,默认为 0 毫秒
    configuration.setMaxRetryInterval(10);
    
    1
    2
    3
    4
    5
    6
    // Make sure to add code blocks to your code group

    # 使用@Retry注解

    # 在方法上挂上@Retry注解

    public interface MyClient {
        // maxRetryCount 为最大重试次数,默认为 0 次
        // maxRetryInterval 为最大重试时间间隔, 单位为毫秒,默认为 0 毫秒
        @Get("/")
        @Retry(maxRetryCount = "3", maxRetryInterval = "10")
        String sendData();
    }
    
    1
    2
    3
    4
    5
    6
    7

    这里的@Retry注解设置了两个属性:

    • maxRetryCount: 请求的最大重试次数,当重试次数大于该属性,将停止触发请求重试流程,默认为0次,即不会触发重试
    • maxRetryInterval: 请求的最大重试时间间隔,单位为毫秒,默认为0毫秒,即没有时间间隔

    当调用该接口的sendData()方法后,若请求失败就会不断进行重试,直到不满足重试条件为止 (即请求成功,或达到最大请求次数限制)

    # 接口上使用@Retry注解

    @Retry注解也可以挂在interface接口类上,代表其下的所有请求方法都设置为此重试配置

    // maxRetryCount 为最大重试次数,默认为 0 次
    // maxRetryInterval 为最大重试时间间隔, 单位为毫秒,默认为 0 毫秒
    // 该接口下每个方法都以此为请求重试配置
    @Retry(maxRetryCount = "3", maxRetryInterval = "10")
    public interface MyClient {
        
        @Get("/test1")
        String sendData1();
    
        @Get("/test2")
        String sendData2();
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    此时,不管调用sendData1()还是sendData2()方法,都会按最大重试3次,最大重试时间间隔10ms为重试属性

    # 重试器

    Retryer 重试器,即重试策略,可以设定每次重试请求之间的时间间隔

    Forest 默认重试器类为 com.dtflys.forest.retryer.BackOffRetryer,它是依据二进制退避算法的重试策略类

    若配置该重试器,重试过程如下:

    • 第一次重试与第一次请求之间间隔 0的2次方 * 1s, 即0s
    • 第二次重试与第一次重试之间间隔 1的2次方 * 1s, 即1s
    • 第三次次重试与第二次重试之间间隔 2的2次方 * 1s, 即4s
    • 后面几次重试时间间隔以此类推,直到达到最大请求次数后停止重试
    • 每次时间间隔不能大于 maxRetryInterval, 若 maxRetryInterval 设置为 10, 则每次间隔只能为 10ms

    您也可以自定义重试器

    // 自定义重试器
    // 继承 BackOffRetryer 类
    public class MyRetryer extends BackOffRetryer {
    
        public MyRetryer(ForestRequest request) {
            super(request);
        }
    
        /**
         * 重写 nextInterval 方法
         * 该方法用于指定每次重试的时间间隔
         * @param currentCount 当前重试次数
         * @return 时间间隔 (时间单位为毫秒)
         */
        @Override
        protected long nextInterval(int currentCount) {
            // 每次重试时间间隔恒定为 1s (1000ms)
            return 1000;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    然后,再通过@Retryer注解绑定该自定义重试器类

    public interface MyClient {
        // maxRetryCount 为最大重试次数,默认为 0 次
        // maxRetryInterval 为最大重试时间间隔, 单位为毫秒,默认为 0 毫秒
        // @Retryer 注解绑定自定义的 MyRetryer 重试器类
        // 将按照自定义的重试策略处理重试间隔时间
        @Get("/")
        @Retry(maxRetryCount = "3", maxRetryInterval = "10")
        @Retryer(MyRetryer.class)
        String sendData();
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    @Retryer注解同样也可以挂在 interface 类上,这里不再赘述。

    # 重试条件

    Forest 请求的重试条件有两种设置模式:

    • 将 请求成功/失败条件 作为重试条件
    • 设置 RetryWhen 重试条件

    这两种模式分别对应于两种不同的重试流程:

    # 重试流程

    1. 请求失败后的重试流程
    请求失败  ✔
     └── 是否未达到请求最大重试次数 (maxRetryCount)  ✔
          ├── 执行 OnRetry 回调函数
          ├── 执行拦截器中的 onRetry 方法
          ├── 发送重试请求
          └── 回到第一步,重试请求是否成功
    
    1
    2
    3
    4
    5
    6
    1. 请求成功后的重试流程
    请求成功  ✔
     └── 是否满足重试条件 (自定义 RetryWhen 接口类条件)  ✔
          └── 是否未达到请求最大重试次数 (maxRetryCount)  ✔
               ├── 执行 OnRetry 回调函数
               ├── 执行拦截器中的 onRetry 方法
               ├── 发送重试请求
               └── 回到第一步,重试请求是否成功,并且是否满足重试条件
    
    1
    2
    3
    4
    5
    6
    7

    # 使用@Success注解设置重试条件

    一般情况只会走第1种重试流程,即直通过请求的成功/失败来判断是否重试,逻辑很简单:请求成功不重试,失败就重试

    此时,可以配合@Success注解和@Retry注解组合使用

    
    public interface MyClient {
        // maxRetryCount 为最大重试次数,默认为 0 次
        // maxRetryInterval 为最大重试时间间隔, 单位为毫秒,默认为 0 毫秒
        // 同时请求成功/失败/重试的判定条件
        // 设置为自定义的 MySuccessCondition 条件类
        @Get("/")
        @Retry(maxRetryCount = "3", maxRetryInterval = "10")
        @Success(condition = MySuccessCondition.class)
        String sendData();
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    这种方式可以同时设置重试最大次数、间隔时间、以及自定义的成功/失败/重试条件。

    # 使用 RetryWhen 接口实现重试条件

    但有些特殊情况,需要在请求成功的情况下也重试,满足一定业务条件后才停止重试,这种情况就需要 RetryWhen 重试条件上场了

    先定义自定义请求重试实现类

    // 自定义重试条件类
    // 需要实现 RetryWhen 接口
    public class MyRetryCondition implements RetryWhen {
        /**
         * 请求重试条件
         * @param req Forest请求对象
         * @param res Forest响应对象
         * @return true 重试,false 不重试
         */
        @Override
        public boolean retryWhen(ForestRequest req, ForestResponse res) {
            // 响应状态码为 203 就重试
            return res.statusIs(203);
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    然后,通过@Retry注解的condition属性指定该类

    public interface MyClient {
        // maxRetryCount 为最大重试次数
        // maxRetryInterval 为最大重试时间间隔, 单位为毫秒
        @Get("/")
        @Retry(maxRetryCount = "3", maxRetryInterval = "10", condition = MyRetryCondition.class)
        String sendData();
    }
    
    1
    2
    3
    4
    5
    6
    7

    若发送请求后,服务端返回203状态码,就不断触发重试,直到服务端不返回203,或达到最大重试次数,停止重试。 若最后一次重试服务端发送的还是203,则认为请求成功,执行onSuccess。

    # 拦截器onRetry方法

    拦截器的onRetry方法会在触发重试时,发送重试请求前被调用

    public class MyRetryInterceptor implements Interceptor<Object> {
    
        /**
         * 在请重试前调用 onRetry 回调函数
         *
         * @param req Forest请求对象
         * @param res Forest响应对象
         */
        @Override
        public void onRetry(ForestRequest req, ForestResponse res) {
            // req.getCurrentRetryCount() 获取请求当前重试次数
            System.out.println("要重试了!当前重试次数:" + req.getCurrentRetryCount());
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    文档导航

    关于如何使用拦截器,请参见《拦截器》

    帮助我们改善此文档 (opens new window)
    上次更新: 2023/03/07, 12:59:48
    🍓 成功/失败条件
    🥂 重定向

    ← 🍓 成功/失败条件 🥂 重定向→

    Theme by Vdoing | Copyright © 2016-2023 公子骏 | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式