亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

golang API請求隊列的實(shí)現(xiàn)

 更新時間:2022年04月24日 16:08:01   作者:wang_yb  
本文主要介紹了golang API請求隊列的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

概要

在調(diào)用第三方 API 的時候, 基本都有訪問限速的限制條件. 第三方的 API 有多個的時候, 就不太好控制訪問速度, 常常會導(dǎo)致 HTTP 429(Too Many Requests) 然后就會有一段時間的禁止訪問.

為了應(yīng)對這種限速的情況, 通過一個簡單的請求隊列來控制訪問的速度, 之后基本沒遇到過 HTTP 429 了.

實(shí)現(xiàn)思路

首先, 每個請求包裝成一個 RequestParam 的 struct, 其中包含請求的地址,類型,參數(shù)以及 response 的 channel.

發(fā)送請求的時候, 只要將 RequestParam 放入請求隊列中即可, 請求完成后, 將 response 放入對應(yīng)的 channel 中.

整個代碼實(shí)現(xià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
  }
  
  // 請求隊列, 本質(zhì)是一個channel
  type RequestQueue struct {
    Queue chan RequestParam
  }
  
  var queue *RequestQueue
  
  // 獲取隊列
  func GetQueue() *RequestQueue {
    return queue
  }
  
  // 初始化隊列
  func InitRequestQueue(size int) {
    queue = &RequestQueue{
      Queue: make(chan RequestParam, size),
    }
  }
  
  // 將請求放入隊列
  func (rq *RequestQueue) Enqueue(p RequestParam) {
    rq.Queue <- p
  }
  
  // 請求隊列服務(wù), 一直等待接受和處理請求
  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!")
  }

這里的請求是用了我自己封裝的 apiclient, 可以根據(jù)實(shí)際情況替換.

在我的應(yīng)用場景里, 只要 api 順序訪問就不會出現(xiàn) HTTP 429 了, 如果這樣覺得速度太快的的話, 可以嘗試在 Run() 函數(shù)中加入一些時間間隔.

  func (rq *RequestQueue) Run() {
    lg := logger.GetLogger()
    for p := range rq.Queue {
       time.Sleep(1 * time.Second)
       // ... 省略的代碼 ...
    }
  
    lg.Info().Msg("request queue finished!")
  }

使用方法

使用很簡單, 首先啟動, 然后每個調(diào)用的地方將 RequestParam 放入隊列并等待 response 即可.

啟動隊列服務(wù) 

func main() {
      // init request queue and start queue service
      util.InitRequestQueue(100)
      queue := util.GetQueue()
      defer close(queue.Queue)
      go queue.Run()
  
      // 其他啟動代碼
  }

使用隊列服務(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
  }

到此這篇關(guān)于golang API請求隊列的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)golang API請求隊列內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言并發(fā)編程 互斥鎖詳情

    Go語言并發(fā)編程 互斥鎖詳情

    在并發(fā)編程中,多個Goroutine訪問同一塊內(nèi)存資源時可能會出現(xiàn)競態(tài)條件,我們需要在臨界區(qū)中使用適當(dāng)?shù)耐讲僮鱽硪员苊飧倯B(tài)條件。Go 語言中提供了很多同步工具,本文將介紹互斥鎖Mutex和讀寫鎖RWMutex的使用方法。
    2021-10-10
  • Golang接口使用教程詳解

    Golang接口使用教程詳解

    在?Go?語言中接口包含兩種含義:它既是方法的集合,?同時還是一種類型并且在Go?語言中是隱式實(shí)現(xiàn)的。本文通過示例詳細(xì)介紹了Golang接口的使用,需要的可以參考一下
    2022-09-09
  • 詳解Golang的GC三色標(biāo)記法

    詳解Golang的GC三色標(biāo)記法

    這篇文章主要為大家介紹了Golang的GC三色標(biāo)記法,文中有詳細(xì)的實(shí)現(xiàn)過程供大家參考,對大家的學(xué)習(xí)或工作有一定幫助,感興趣的可以跟著小編一來看看
    2023-05-05
  • Go語言中slice作為參數(shù)傳遞時遇到的一些“坑”

    Go語言中slice作為參數(shù)傳遞時遇到的一些“坑”

    這篇文章主要給大家介紹了關(guān)于Go語言中slice作為參數(shù)傳遞時遇到的一些“坑”,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03
  • Golang中runtime的使用詳解

    Golang中runtime的使用詳解

    這篇文章主要介紹了Golang中runtime的使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • golang bad file descriptor問題的解決方法

    golang bad file descriptor問題的解決方法

    這篇文章主要給大家介紹了golang bad file descriptor問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • 詳解Golang中單元測試的使用

    詳解Golang中單元測試的使用

    單元測試是檢測你寫的一個函數(shù)是否具備安全性的一次檢測,這篇文章主要為大家詳細(xì)介紹了Golang中單元測試的具體使用,希望對大家有所幫助
    2023-07-07
  • Go語言編程入門超級指南

    Go語言編程入門超級指南

    這篇文章主要介紹了Go語言編程的入門指南,包括對Go的變量及函數(shù)的基本介紹,需要的朋友可以參考下
    2016-01-01
  • go語言實(shí)現(xiàn)LRU緩存的示例代碼

    go語言實(shí)現(xiàn)LRU緩存的示例代碼

    LRU是一種常見的緩存淘汰策略,用于管理緩存中的數(shù)據(jù),本文主要介紹了go語言實(shí)現(xiàn)LRU緩存的示例代碼,具有一定的參考價值,感興趣的可以了解一下
    2024-02-02
  • Go語言學(xué)習(xí)之條件語句使用詳解

    Go語言學(xué)習(xí)之條件語句使用詳解

    這篇文章主要介紹了Go語言中條件語句的使用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04

最新評論