網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
概要
在調(diào)用第三方 API 的時(shí)候, 基本都有訪問(wèn)限速的限制條件. 第三方的 API 有多個(gè)的時(shí)候, 就不太好控制訪問(wèn)速度, 常常會(huì)導(dǎo)致 HTTP 429(Too Many Requests) 然后就會(huì)有一段時(shí)間的禁止訪問(wèn).
為了應(yīng)對(duì)這種限速的情況, 通過(guò)一個(gè)簡(jiǎn)單的請(qǐng)求隊(duì)列來(lái)控制訪問(wèn)的速度, 之后基本沒(méi)遇到過(guò) HTTP 429 了.
實(shí)現(xiàn)思路
首先, 每個(gè)請(qǐng)求包裝成一個(gè) RequestParam 的 struct, 其中包含請(qǐng)求的地址,類型,參數(shù)以及 response 的 channel.
發(fā)送請(qǐng)求的時(shí)候, 只要將 RequestParam 放入請(qǐng)求隊(duì)列中即可, 請(qǐng)求完成后, 將 response 放入對(duì)應(yīng)的 channel 中.
整個(gè)代碼實(shí)現(xiàn)很簡(jiǎn)單:
package util import ( "fmt" apiclient "gitee.com/wangyubin/gutils/api_client" "gitee.com/wangyubin/gutils/logger" ) // request 包含的內(nèi)容 type RequestParam struct { Api string Method string JsonReq interface{} Resp chan []byte } // 請(qǐng)求隊(duì)列, 本質(zhì)是一個(gè)channel type RequestQueue struct { Queue chan RequestParam } var queue *RequestQueue // 獲取隊(duì)列 func GetQueue() *RequestQueue { return queue } // 初始化隊(duì)列 func InitRequestQueue(size int) { queue = &RequestQueue{ Queue: make(chan RequestParam, size), } } // 將請(qǐng)求放入隊(duì)列 func (rq *RequestQueue) Enqueue(p RequestParam) { rq.Queue <- p } // 請(qǐng)求隊(duì)列服務(wù), 一直等待接受和處理請(qǐng)求 func (rq *RequestQueue) Run() { lg := logger.GetLogger() for p := range rq.Queue { var resp []byte var err error switch p.Method { case "GET": resp, err = apiclient.GetJson(p.Api, p.JsonReq) case "POST": resp, err = apiclient.PostJson(p.Api, p.JsonReq) default: err = fmt.Errorf("Wrong type of METHOD(%s)\n", p.Method) } if err != nil { lg.Err(err).Msg("access api error: " + p.Api) continue } if p.Resp != nil { p.Resp <- resp close(p.Resp) } } lg.Info().Msg("request queue finished!") }
這里的請(qǐng)求是用了我自己封裝的 apiclient, 可以根據(jù)實(shí)際情況替換.
在我的應(yīng)用場(chǎng)景里, 只要 api 順序訪問(wèn)就不會(huì)出現(xiàn) HTTP 429 了, 如果這樣覺(jué)得速度太快的的話, 可以嘗試在 Run() 函數(shù)中加入一些時(shí)間間隔.
func (rq *RequestQueue) Run() { lg := logger.GetLogger() for p := range rq.Queue { time.Sleep(1 * time.Second) // ... 省略的代碼 ... } lg.Info().Msg("request queue finished!") }
使用方法
使用很簡(jiǎn)單, 首先啟動(dòng), 然后每個(gè)調(diào)用的地方將 RequestParam 放入隊(duì)列并等待 response 即可.
啟動(dòng)隊(duì)列服務(wù)?
func main() { // init request queue and start queue service util.InitRequestQueue(100) queue := util.GetQueue() defer close(queue.Queue) go queue.Run() // 其他啟動(dòng)代碼 }
使用隊(duì)列服務(wù)
func Request(param1 string, param2 int) error { api := "http://xxxx.com" api = fmt.Sprintf("%s?period=%s&size=%d", api, param1, param2) queue := util.GetQueue() param := util.RequestParam{ Api: api, Method: "GET", Resp: make(chan []byte, 1), } queue.Enqueue(param) var respData struct { Status string `json:"status"` Data []model.Data `json:"data"` } var err error for resp := range param.Resp { err = json.Unmarshal(resp, &respData) if err != nil { lg.Err(err).Msg("unmarshal json error") return err } } fmt.Println(respData) return err }
原文鏈接:https://www.cnblogs.com/wang_yb/p/13018901.html
相關(guān)推薦
- 2022-05-26 mongoDB數(shù)據(jù)庫(kù)索引快速入門(mén)指南_MongoDB
- 2022-01-30 visibilitychange事件在移動(dòng)端開(kāi)發(fā)的使用
- 2022-07-04 Python中字典常用操作的示例詳解_python
- 2022-05-02 DevOps自動(dòng)化組件RUNDECK開(kāi)發(fā)部署使用說(shuō)明_服務(wù)器其它
- 2022-09-04 k8s查看pod日志的幾種實(shí)用方法匯總_云其它
- 2022-12-12 Android?Cocos?Creator游戲開(kāi)發(fā)平臺(tái)打包優(yōu)化實(shí)現(xiàn)方案_Android
- 2022-06-08 SpringCache通用緩存學(xué)習(xí)
- 2022-12-23 C++中關(guān)于getchar()的使用方法_C 語(yǔ)言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支