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

HTTP 直連接口穩定性提升:幂等設計 + 狀態機 + 重試熔斷

     編輯:程式設計綜合問答

場景約束

  • 雙系統通過 HTTP 直連同步數據。
  • 不可引入 MQ、Kafka 等中間件。
  • 需解決:網絡抖動、超時、對端異常、重複提交、數據不一致。

核心模式:幂等性 + 狀態機 + 指數退避重試 + 熔斷

1. 幂等鍵設計(去重核心)

// 請求頭或體攜帶
Idempotency-Key: biz_type:order:20240520:123456  // 業務唯一標識

// 服務端處理
public Result handle(Request req) {
    String key = req.getHeader("Idempotency-Key");
    if (redis.setIfAbsent(key, "PROCESSING", 30, TimeUnit.MINUTES)) {
        try {
            doBusiness(req);
            redis.set(key, "SUCCESS");
            return success();
        } catch (Exception e) {
            redis.delete(key);  // 失敗釋放鎖,允許重試
            throw e;
        }
    }
    String status = redis.get(key);
    if ("SUCCESS".equals(status)) return success("已處理");
    return conflict("正在處理中");  // PROCESSING 狀態
}

2. 發送端狀態機持久化

enum Status { INIT, SENDING, SUCCESS, FAILED, COMPENSATING }

@Table
class HttpTask {
    String idempotencyKey;
    String payloadJson;
    Status status;
    int retryCount;
    LocalDateTime nextRetryTime;
    // ...
}

// 定時掃描 INIT/FAILED/COMPENSATING 且 nextRetryTime <= now 的任務發送
// 發送前更新 status=SENDING
// 成功更新 SUCCESS,失敗 retryCount++、計算下次退避時間
// 超過最大重試進入 COMPENSATING(人工/異步補償)

3. 指數退避 + 抖動重試策略

// 重試間隔 = min(base * 2^retry + random(0, jitter), maxInterval)
int base = 1000; // 1s
int maxInterval = 60000; // 1min
int maxRetries = 5;

long nextInterval = Math.min(base * (1L << retryCount) + random.nextInt(500), maxInterval);

4. 熔斷器防雪崩

// 使用 Resilience4j / Hystrix / Sentinel
CircuitBreaker cb = CircuitBreaker.ofDefaults("http-client");
Supplier decorated = CircuitBreaker.decorateSupplier(cb, () -> httpClient.post(url, body));
Try.ofSupplier(decorated)
   .retry(3, Schedule.of(1000, 2.0))  // 重試 3 次,指數退避
   .onFailure(e -> log.error("熔斷/重試耗盡", e))
   .get();

關鍵檢查清單

風險對策
網絡抖動導致超時設置合理連接/讀取超時(如 3s/10s),啟用重試
對端處理超時但實際成功幂等鍵去重,發送端狀態機最終一致性
對端異常拋錯區分可重試錯誤(5xx, timeout)與不可重試(4xx, 業務拒絕)
大量積壓導致發送端 OOM任務持久化到 DB/Redis,消費者拉取處理,背壓控制
數據不一致無法自動修復定期對賬任務(T+1 全量比對),差異進入人工補償池

總結

HTTP 直連穩定性 = **幂等鍵去重** + **發送端狀態機持久化** + **指數退避重試** + **熔斷防雪崩** + **定期對賬補償**。不引入 MQ 也能構建高可靠同步鏈路,關鍵在於**將「不可靠的網絡」轉化為「可靠的狀態流轉」**。

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