You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Golang中实现每5分钟调用REST API获取Token的重试逻辑

Go实现定时调用API并添加Token获取重试逻辑

核心功能实现

要完成两个核心需求:

  • 每5分钟自动触发一次API调用
  • 调用失败时(网络错误、非预期响应)自动重试

重试逻辑封装

先封装带重试机制的HTTP请求函数,覆盖网络错误、非200状态码、JSON解码失败等场景,支持自定义重试次数和间隔:

import (
    "encoding/json"
    "fmt"
    "net/http"
    "time"
)

// 定义API响应对应的结构体(根据实际返回字段调整)
type Response struct {
    Key     string `json:"Key"`
    Account string `json:"Account"`
}

// fetchTokenWithRetry 带重试的Token获取函数
func fetchTokenWithRetry(url string, maxRetries int, retryDelay time.Duration) (*Response, error) {
    for attempt := 0; attempt < maxRetries; attempt++ {
        resp, err := http.Get(url)
        if err != nil {
            if attempt == maxRetries-1 {
                return nil, fmt.Errorf("第%d次请求失败: %w", attempt+1, err)
            }
            fmt.Printf("第%d次请求失败,%d秒后重试: %v\n", attempt+1, retryDelay/time.Second, err)
            time.Sleep(retryDelay)
            continue
        }
        defer resp.Body.Close()

        // 检查响应状态码
        if resp.StatusCode != http.StatusOK {
            if attempt == maxRetries-1 {
                return nil, fmt.Errorf("第%d次请求返回非200状态码: %d", attempt+1, resp.StatusCode)
            }
            fmt.Printf("第%d次请求返回状态码%d,%d秒后重试\n", attempt+1, resp.StatusCode, retryDelay/time.Second)
            time.Sleep(retryDelay)
            continue
        }

        // 解码响应JSON
        var tokenResp Response
        if err := json.NewDecoder(resp.Body).Decode(&tokenResp); err != nil {
            if attempt == maxRetries-1 {
                return nil, fmt.Errorf("第%d次请求解码失败: %w", attempt+1, err)
            }
            fmt.Printf("第%d次请求解码失败,%d秒后重试: %v\n", attempt+1, retryDelay/time.Second, err)
            time.Sleep(retryDelay)
            continue
        }

        // 成功获取到Token,直接返回
        return &tokenResp, nil
    }
    return nil, fmt.Errorf("已达到最大重试次数%d,请求仍失败", maxRetries)
}

定时任务实现

使用time.Ticker实现每5分钟触发一次调用,同时监听系统退出信号保证优雅关闭:

import (
    "os"
    "os/signal"
    "syscall"
)

func main() {
    apiURL := "https://mydadisjoke.com/Acct"
    maxRetries := 3          // 最大重试次数
    retryDelay := 5 * time.Second // 每次重试间隔
    interval := 5 * time.Minute    // 定时调用间隔

    // 初始化Ticker
    ticker := time.NewTicker(interval)
    defer ticker.Stop()

    // 监听退出信号(Ctrl+C、kill命令)
    stopChan := make(chan os.Signal, 1)
    signal.Notify(stopChan, syscall.SIGINT, syscall.SIGTERM)

    // 首次启动立即执行一次
    fmt.Println("首次执行Token获取...")
    if resp, err := fetchTokenWithRetry(apiURL, maxRetries, retryDelay); err != nil {
        fmt.Printf("首次获取Token失败: %v\n", err)
    } else {
        fmt.Printf("成功获取Token: Key=%s, Account=%s\n", resp.Key, resp.Account)
    }

    // 定时循环执行
    for {
        select {
        case <-ticker.C:
            fmt.Println("\n定时触发Token获取...")
            resp, err := fetchTokenWithRetry(apiURL, maxRetries, retryDelay)
            if err != nil {
                fmt.Printf("定时获取Token失败: %v\n", err)
                continue
            }
            fmt.Printf("成功获取Token: Key=%s, Account=%s\n", resp.Key, resp.Account)
        case <-stopChan:
            fmt.Println("\n程序收到退出信号,正在关闭...")
            return
        }
    }
}

关键细节说明

  • 重试触发条件:覆盖网络请求失败、响应状态码非200、JSON解码失败三种常见错误场景
  • 重试策略:可通过maxRetries和retryDelay调整重试次数和间隔,避免频繁请求给API造成压力
  • 定时逻辑:首次启动立即执行一次,之后每5分钟触发,符合"定期更新Token"的常见需求
  • 优雅关闭:监听系统退出信号,保证程序退出时能清理资源

内容的提问来源于stack exchange,提问作者Sri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 13:23:20