脚本如何随机化重试间隔时长

wen 实用脚本 27

本文目录导读:

脚本如何随机化重试间隔时长

  1. JavaScript (Node.js)
  2. Python
  3. 带指数退避的随机化 (推荐)
  4. Shell脚本
  5. Java
  6. Go
  7. 最佳实践建议

JavaScript (Node.js)

async function retryWithRandomDelay(fn, maxRetries = 3) {
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
        try {
            return await fn();
        } catch (error) {
            if (attempt === maxRetries) throw error;
            // 随机延迟 1-5 秒
            const delay = 1000 + Math.random() * 4000;
            console.log(`Attempt ${attempt} failed, retrying in ${delay.toFixed(0)}ms`);
            await new Promise(resolve => setTimeout(resolve, delay));
        }
    }
}

Python

import time
import random
def retry_with_random_delay(func, max_retries=3, min_delay=1, max_delay=5):
    for attempt in range(1, max_retries + 1):
        try:
            return func()
        except Exception as e:
            if attempt == max_retries:
                raise e
            # 随机延迟 (秒)
            delay = random.uniform(min_delay, max_delay)
            print(f"Attempt {attempt} failed, retrying in {delay:.2f}s")
            time.sleep(delay)
# 使用示例
def api_call():
    # 你的API调用逻辑
    pass
retry_with_random_delay(api_call)

带指数退避的随机化 (推荐)

import time
import random
def retry_with_exponential_backoff(func, max_retries=5, base_delay=1, max_delay=30):
    for attempt in range(1, max_retries + 1):
        try:
            return func()
        except Exception as e:
            if attempt == max_retries:
                raise e
            # 指数退避 + 随机抖动
            delay = min(base_delay * (2 ** (attempt - 1)), max_delay)
            jitter = random.uniform(0, delay * 0.5)  # 增加最多50%的随机性
            total_delay = delay + jitter
            print(f"Attempt {attempt} failed, retrying in {total_delay:.2f}s")
            time.sleep(total_delay)

Shell脚本

#!/bin/bash
retry_with_random_delay() {
    local max_retries=3
    local attempt=1
    while [ $attempt -le $max_retries ]; do
        if "$@"; then
            return 0
        fi
        if [ $attempt -eq $max_retries ]; then
            return 1
        fi
        # 随机延迟 1-5 秒
        local delay=$((1 + RANDOM % 5))
        echo "Attempt $attempt failed, retrying in ${delay}s"
        sleep $delay
        ((attempt++))
    done
}
# 使用
retry_with_random_delay curl https://api.example.com/endpoint

Java

import java.util.Random;
public class RetryUtil {
    private static final Random random = new Random();
    public static <T> T retryWithRandomDelay(Callable<T> callable, int maxRetries) throws Exception {
        for (int attempt = 1; attempt <= maxRetries; attempt++) {
            try {
                return callable.call();
            } catch (Exception e) {
                if (attempt == maxRetries) {
                    throw e;
                }
                // 随机延迟 1000-5000 毫秒
                int delay = 1000 + random.nextInt(4000);
                System.out.println("Attempt " + attempt + " failed, retrying in " + delay + "ms");
                Thread.sleep(delay);
            }
        }
        return null; // should never reach here
    }
}

Go

package main
import (
    "fmt"
    "math/rand"
    "time"
)
func retryWithRandomDelay(fn func() error, maxRetries int) error {
    for attempt := 1; attempt <= maxRetries; attempt++ {
        err := fn()
        if err == nil {
            return nil
        }
        if attempt == maxRetries {
            return err
        }
        // 随机延迟 1-5 秒
        delay := time.Duration(1000+rand.Intn(4000)) * time.Millisecond
        fmt.Printf("Attempt %d failed, retrying in %v\n", attempt, delay)
        time.Sleep(delay)
    }
    return fmt.Errorf("all retries failed")
}

最佳实践建议

  1. 结合指数退避delay = min(base * 2^attempt, max_delay) + random_jitter
  2. 添加随机抖动:在基础延迟上增加 0-50% 的随机值
  3. 设置最大延迟:避免过长等待
  4. 记录重试日志:便于调试

选择哪种方法取决于你的具体需求和编程环境。

抱歉,评论功能暂时关闭!