首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 線程實現定時重試:間隔 10 分鐘最多 5 次,收到 OK 自動停止

     編輯:Java 綜合教學

回調通知重試機制:Runnable + sleep 實現指數退避前身的固定間隔重試邏輯

第三方回調通知可能因網絡抖動、對方服務暫時不可用導致失敗。業務常見需求:發起重試,間隔固定時間(如 10 分鐘),最多重試 N 次(如 5 次),收到成功響應立即停止。本文提供基於 Runnable + Thread.sleep 的輕量級實現,適合低併發、無分布式協調需求的場景。

一、 核心實現代碼

public class RequestTask implements Runnable {
    private final String url;
    private final String param;
    private volatile String status = "false"; // volatile 保證可見性

    public RequestTask(String url, String param) {
        this.url = url;
        this.param = param;
    }

    @Override
    public void run() {
        int maxRetries = 5;
        int attempt = 1;

        while (attempt <= maxRetries) {
            String result = HttpRequest.sendPost(url, param); // 假設工具類同步發送
            if ("ok".equalsIgnoreCase(result)) {
                status = "ok";
                log.info("第 {} 次重試成功,停止重試", attempt);
                break;
            }

            log.warn("第 {} 次重試失敗,響應: {}", attempt, result);
            attempt++;

            if (attempt <= maxRetries) {
                try {
                    Thread.sleep(10 * 60 * 1000L); // 10 分鐘
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt(); // 恢復中斷狀態
                    log.error("重試線程被中斷", e);
                    break;
                }
            }
        }

        if (!"ok".equals(status)) {
            log.error("重試 {} 次均失敗,需人工介入或進入死信隊列", maxRetries);
        }
    }

    public String getStatus() { return status; }
}

二、 使用方式

// 業務觸發點(如收到異步通知處理失敗)
RequestTask task = new RequestTask("https://api.partner.com/callback", "orderId=12345&status=paid");
new Thread(task, "Callback-Retry-Order12345").start();

// 異步執行,主線程不阻塞。可通過 task.getStatus() 或異步回調感知最終結果。

三、 關鍵點解析

點說明
volatile status跨線程可見性,主線程可輪詢或回調讀取最新狀態。
Thread.sleep阻塞當前線程,釋放 CPU。簡單但佔用線程資源,高併發下慎用。
中斷處理捕獲 InterruptedException 後調用 Thread.currentThread().interrupt() 恢復中斷標誌,遵守線程中斷協議。
同步 HTTP 調用HttpRequest.sendPost 假設為同步阻塞調用。生產環境建議設置連接/讀取超時 (如 5s/10s)。
線程命名new Thread(task, "名稱") 便於日志追蹤、Arthas 排查、監控識別。

四、 進階優化方向(生產級重試框架特性)

  1. 指數退避 + 抖動:sleep = base * 2^attempt + random(0, jitter),避免驚群效應。
  2. ScheduledExecutorService:替代手動 sleep,支持定時調度、取消、單線程串行重試不佔用業務線程池。
  3. 異步非阻塞 HTTP:HttpClient (Apache) / WebClient (Spring 5+) / OkHttp 異步回調,釋放線程。
  4. 狀態持久化:重試任務入庫 (DB/Redis),應用重啟後自動恢復未完成重試。
  5. 分布式鎖:集群環境防止同一任務被多節點重複重試 (Redis SETNX / Zookeeper)。
  6. 熔斷器:連續失敗達閾值自動熔斷,停止重試保護下游 (Resilience4j / Hystrix)。

五、 總結

本實現以 50 行核心代碼 解決固定間隔有限次數重試問題,適合單體應用、低頻回調場景。隨著業務增長,建議遷移至成熟重試框架 (Spring Retry、Resilience4j) 或引入消息隊列 (RabbitMQ 延遲隊列、Kafka 重試主題) 實現可靠、可觀測、可擴展的重試體系。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved