功能说明
该示例提供一个可复用的重试函数:接收最大尝试次数与要执行的命令,命令失败时按 1 秒、2 秒、4 秒、8 秒的节奏等待后重试,直到成功或次数耗尽。失败时向标准错误输出诊断信息并以非零码返回,使调用方与管道能感知失败。
关键代码
函数用 shift 把首个参数取出后,把剩余参数当作命令整体执行,从而保留参数中的空格与引号。“$@”加引号是正确传递带空格参数的关键。until 循环在命令成功时结束;每次失败递增尝试计数并在达到上限时返回 1。延迟每轮翻倍实现指数退避。set -euo pipefail 让脚本更早暴露错误。
使用注意
该函数只按固定指数退避,未加抖动,多实例同时重试可能同步成惊群,生产脚本应加入随机抖动。重试只应针对可恢复的失败,命令若因输入错误而失败,重试只是浪费时间,可结合 curl 的 –fail 与退出码判断。务必保留每次调用的日志以便排查。重试命令必须幂等,写入型操作需要幂等键,否则一次超时可能变成两次副作用。
代码示例
#!/usr/bin/env bash
set -euo pipefail
retry() {
local max_attempts="$1"; shift
local delay=1
local attempt=0
until "$@"; do
attempt=$((attempt + 1))
if (( attempt >= max_attempts )); then
echo "retry: giving up after ${attempt} attempts" >&2
return 1
fi
echo "retry: attempt ${attempt} failed, sleeping ${delay}s" >&2
sleep "$delay"
delay=$((delay * 2))
done
}
# 用法示例:最多 5 次,命令失败时按 1s、2s、4s、8s 退避
retry 5 curl -fsS --max-time 10 https://api.example.com/health