如何在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
相关产品推荐
相关产品推荐

