Curl Retry Backoff Transient Errors

Retry curl against flaky endpoints with retry flags, exponential backoff, and server-side Retry-After header respect.

BashResilience

Code

snippet
#!/usr/bin/env bash
set -euo pipefail

readonly URL="https://api.example.com/v1/report"
readonly MAX_RETRIES=4

fetch_report() {
  local attempt=0
  local wait=1

  while (( attempt < MAX_RETRIES )); do
    local body
    if body=$(curl -sf --max-time 10 \
        -H "Authorization: Bearer ${API_TOKEN}" \
        --retry "$(( MAX_RETRIES - attempt ))" \
        --retry-delay "${wait}" \
        --retry-connrefused \
        "${URL}"); then
      echo "$body" | jq -r '.rows | length'
      return 0
    fi

    local code=$?
    if (( code == 22 )); then
      # 429/5xx:优先读服务端的 Retry-After
      local retry_after
      retry_after=$(curl -s -o /dev/null -D - "${URL}" \
        | awk -F': ' 'tolower($1)=="retry-after" {gsub(/\r/, "", $2); print $2}')
      if [[ "${retry_after}" =~ ^[0-9]+$ ]]; then
        wait=$(( retry_after + 1 ))
      fi
    fi

    (( attempt++ )) || true
    (( attempt < MAX_RETRIES )) || break
    echo "第 ${attempt} 次失败,${wait}s 后重试" >&2
    sleep "${wait}"
    wait=$(( wait * 2 ))   # 指数退避
  done

  echo "Error: 重试耗尽仍无法获取报告" >&2
  return 1
}

: "${API_TOKEN:?环境变量 API_TOKEN 未设置}"
fetch_report