利用多线程Schedule实现非阻塞消息发送重试

1.创建重试逻辑 

import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Supplier;

@Slf4j
public class RetryHandler {

    private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(4);

     /**
     * 
     * @param message 需要重试的业务逻辑
     * @param success 业务回调返回值
     * @param retryCount 重试次数
     * @param retryTime 重试时间
     * @param <T>
     */
    public static <T> void send(Supplier<T> message, Consumer<T> success, int retryCount, int retryTime) {
        try {
            T t = message.get();
        } catch (Exception e) {
            log.error("消息发送失败,重试次数:{}, 重试时间:{}, 异常原因:{}", retryCount, retryTime, e.getLocalizedMessage());
            executorService.schedule(new AsycSendTask<T>(retryCount, --retryCount, retryTime, message, success), retryTime, TimeUnit.MILLISECONDS);
            throw e; 
        }
    }


    private static class AsycSendTask<T> implements Runnable {

        private int retryCount;
        private int restRetryCount;
        private int retryTime;
        private Supplier<T> fun;
        private Consumer<T> success;

        public AsycSendTask(int retryCount, int restRetryCount, int retryTime, Supplier<T> fun, Consumer<T> success) {
            this.retryCount = retryCount;
            this.restRetryCount = restRetryCount;
            this.retryTime = retryTime;
            this.fun = fun;
            this.success = success;
        }

        @Override
        public void run() {
            try {
                T result = fun.get();
                log.info("重试{}次后发送成功", (retryCount - restRetryCount));
                success.accept(result);
            } catch (Exception e) {
                if (restRetryCount <= 0) {
                    log.error("重试{}后失败,丢弃,失败原因:{}", restRetryCount, e.getLocalizedMessage());
                } else {
                    log.error("重试次数剩余:{}", restRetryCount);
                    restRetryCount--;
                    executorService.schedule(new AsycSendTask<>(retryCount, restRetryCount, retryTime, fun, success),retryTime, TimeUnit.MILLISECONDS);
                }
            }
        }

    }

}

2. 重试调用测试

import java.util.concurrent.atomic.AtomicInteger;

public class Test {
    private static AtomicInteger count = new AtomicInteger(0);

    public static void main(String[] args) {
        RetryHandler.send(() -> test(), rep -> System.out.println(rep), 3, 200);
    }

    public static String test() {
        count.incrementAndGet();
        if (count.get() <= 3) {
            throw new RuntimeException("test");
        }
        return "重试成功";
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值