广告位联系
返回顶部
分享到

Java实现自定义重试工具类介绍

C#教程 来源:互联网 作者:佚名 发布时间:2024-11-30 22:57:27 人浏览
摘要

Spring-retry、guava的Retry都提供有重试工具,但二者均存在一个确缺点,即如果重试等待过程中会一直阻塞工作线程,这对于在生产环境使用是存在风险的,如果存在大量长时间等待的重试任务将

Spring-retry、guava的Retry都提供有重试工具,但二者均存在一个确缺点,即如果重试等待过程中会一直阻塞工作线程,这对于在生产环境使用是存在风险的,如果存在大量长时间等待的重试任务将会耗尽系统线程资源,下文基于线程池来完成一个简易的重试工具类。

核心思想

将任务封装为一个task,将任务的重试放入可调度的线程池中完成执行,避免在重试间隔中,线程陷入无意义的等待,同时将重试机制抽象为重试策略。

代码实现

重试工具类

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

package com.huakai.springenv.retry.v2;

 

import lombok.extern.slf4j.Slf4j;

 

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

import java.util.concurrent.atomic.AtomicInteger;

import java.util.function.Function;

 

@Slf4j

public class RetryUtil {

 

    public static ExecutorService EXECUTOR = Executors.newFixedThreadPool(1);

    private static final ScheduledExecutorService SCHEDULER_EXECUTOR = Executors.newScheduledThreadPool(20);

 

 

    /**

     * 任务重试

     * @param actualTaskFunction 执行的任务函数

     * @param resultHandler 任务结果处理器

     * @param maxRetry 最大重试次数

     * @param retryStrategy 重试策略

     */

    public static void retryTask(

            Function<Integer, String> actualTaskFunction,

            Function<String, Boolean> resultHandler,

            int maxRetry,

            RetryStrategy retryStrategy // 使用策略模式

    ) {

        Runnable runnable = new Runnable() {

            final AtomicInteger retryCount = new AtomicInteger(); // 当前重试次数

            final AtomicInteger maxRetryCount = new AtomicInteger(maxRetry); // 最大重试次数

 

            @Override

            public void run() {

                String taskResult = actualTaskFunction.apply(retryCount.get()); // 执行任务

                Boolean taskSuccess = resultHandler.apply(taskResult); // 处理任务结果

                if (taskSuccess) {

                    if (retryCount.get() > 1) {

                        log.info("任务重试成功,重试次数:{}", retryCount.get());

                    }

                    return; // 任务成功,不需要再重试

                }

 

                if (retryCount.incrementAndGet() == maxRetryCount.get()) {

                    log.warn("任务重试失败,重试次数:{}", retryCount.get());

                    return; // 达到最大重试次数,停止重试

                }

 

                // 获取重试间隔

                long delay = retryStrategy.getDelay(retryCount.get());

                TimeUnit timeUnit = retryStrategy.getTimeUnit(retryCount.get());

 

                // 安排下次重试

                SCHEDULER_EXECUTOR.schedule(this, delay, timeUnit);

                log.info("任务重试失败,等待 {} {} 后再次尝试,当前重试次数:{}", delay, timeUnit, retryCount.get());

            }

        };

        EXECUTOR.execute(runnable); // 执行任务

    }

 

    public static void main(String[] args) {

        // 使用指数退避重试策略

        RetryStrategy retryStrategy = new ExponentialBackoffRetryStrategy(1, TimeUnit.SECONDS);

 

        retryTask(

                retryCount -> "task result",

                taskResult -> Math.random() < 0.1,

                5,

                retryStrategy

        );

    }

}

重试策略

指数退避

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

package com.huakai.springenv.retry.v2;

 

import java.util.concurrent.TimeUnit;

 

/**

 * 指数退避重试策略

 */

public class ExponentialBackoffRetryStrategy implements RetryStrategy {

    private final long initialDelay;

    private final TimeUnit timeUnit;

 

    public ExponentialBackoffRetryStrategy(long initialDelay, TimeUnit timeUnit) {

        this.initialDelay = initialDelay;

        this.timeUnit = timeUnit;

    }

 

    @Override

    public long getDelay(int retryCount) {

        return (long) (initialDelay * Math.pow(2, retryCount - 1)); // 指数退避

    }

 

    @Override

    public TimeUnit getTimeUnit(int retryCount) {

        return timeUnit;

    }

}

自定义重试间隔时间

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

package com.huakai.springenv.retry.v2;

 

import java.util.List;

import java.util.concurrent.TimeUnit;

 

/**

 * 自定义重试间隔时间的重试策略

 */

public class CustomerIntervalRetryStrategy implements RetryStrategy {

    // 配置重试间隔和时间单位

    List<RetryInterval> retryIntervals;

 

 

    public CustomerIntervalRetryStrategy(List<RetryInterval> retryIntervals) {

        this.retryIntervals = retryIntervals;

    }

 

    @Override

    public long getDelay(int retryCount) {

        return retryIntervals.get(retryCount).getDelay();

    }

 

    @Override

    public TimeUnit getTimeUnit(int retryCount){

        return retryIntervals.get(retryCount).getTimeUnit();

    }

}

固定间隔

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

package com.huakai.springenv.retry.v2;

 

import java.util.concurrent.TimeUnit;

 

/**

 * 固定间隔重试策略

 */

public class FixedIntervalRetryStrategy implements RetryStrategy {

    private final long interval;

    private final TimeUnit timeUnit;

 

    public FixedIntervalRetryStrategy(long interval, TimeUnit timeUnit) {

        this.interval = interval;

        this.timeUnit = timeUnit;

    }

 

    @Override

    public long getDelay(int retryCount) {

        return interval;

    }

 

    @Override

    public TimeUnit getTimeUnit(int retryCount) {

        return timeUnit;

    }

}


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。

您可能感兴趣的文章 :

原文链接 :
相关文章
  • 在idea中利用maven实现多环境配置自动打包的流程

    在idea中利用maven实现多环境配置自动打包的流程
    spring的多环境配置 spring提供了多环境配置文件的功能,只需要根据配置文件后缀即可加载对应的配置文件 1 2 3 4 spring: profiles: # 修改后缀即
  • Java实现自定义重试工具类介绍
    Spring-retry、guava的Retry都提供有重试工具,但二者均存在一个确缺点,即如果重试等待过程中会一直阻塞工作线程,这对于在生产环境使用是
  • C#中SetStyle的具体使用介绍
    在C#的Windows Forms应用程序中,SetStyle方法是Control类的一个成员,用于启用或禁用特定的控件样式。这些样式控制控件的不同行为和外观。以
  • C# WinForm实现画笔签名功能介绍

    C# WinForm实现画笔签名功能介绍
    实现效果 签名功能的显示界面如下图: 该效果主要实现如下功能: 1、提供画布,设计画笔类,实现画笔签名 2、点击重签按钮清空画布
  • C#文字识别API场景解析、表格识别提取功能实现
    在快节奏的工作与生活环境中,如何提高企业工作效率、提升用户体验成为了人们追求的共同目标。针对市场发展需求,一种将任意场景图
  • c#线性回归和多项式拟合示例详解
    1. 线性回归 公式:线性回归的目标是拟合一条直线,形式为: y=mx+by=mx+b 其中: yy是因变量(目标值) xx是自变量(特征值) mm是斜率(s
  • C#删除Word文档中的段落的方法

    C#删除Word文档中的段落的方法
    免费.NET Word 库 -Free Spire.Doc for .NET。该库支持实现创建、编辑、转换Word文档等多种操作,可以直接在Visual Studio中通过NuGet搜索 FreeSpire.Doc,然
  • c#强制类型转换int方式
    c#强制类型转换int 在 C# 中有三种方法把其它类型转为整型,分别是 : int.Parse() 强制转换(int) Convert.ToInt32() 下面探讨它们各自的特点及效率
  • C#生成exe可执行文件的常用方法

    C#生成exe可执行文件的常用方法
    生成可执行文件的方法常用的有2种设置 一、常用2种方法 1、生成菜单 2、项目文件夹下的可执行文件 3、项目菜单---S71500Comm属性
  • 使用C#快速搭建一个在windows运行的exe应用

    使用C#快速搭建一个在windows运行的exe应用
    这是一个比较旧的内容,但是一直都没有空写,今天花点时间,把我掌握的C# 分享给初学的人或者感兴趣的人,希望能对你有一定帮助 1.1
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计