最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2022年04月24日 16:08:01   作者:wang_yb  
本文主要介紹了golang API請求隊(duì)列的實(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)對這種限速的情況, 通過一個簡單的請求隊(duì)列來控制訪問的速度, 之后基本沒遇到過 HTTP 429 了.

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

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

發(fā)送請求的時候, 只要將 RequestParam 放入請求隊(duì)列中即可, 請求完成后, 將 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
  }
  
  // 請求隊(duì)列, 本質(zhì)是一個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),
    }
  }
  
  // 將請求放入隊(duì)列
  func (rq *RequestQueue) Enqueue(p RequestParam) {
    rq.Queue <- p
  }
  
  // 請求隊(duì)列服務(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 放入隊(duì)列并等待 response 即可.

啟動隊(duì)列服務(wù) 

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

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

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

相關(guān)文章

  • Go解析不定JSON數(shù)據(jù)的方法詳解

    Go解析不定JSON數(shù)據(jù)的方法詳解

    在開發(fā)中常常會碰到很多JSON類型的數(shù)據(jù)進(jìn)行交互,而其中有很多JSON數(shù)據(jù)你是不能確定它的字段和結(jié)構(gòu)的,而Go語言是一門靜態(tài)強(qiáng)類型的語言,在進(jìn)行JSON解析的時候必須要確定字段的類型,本文給大家介紹了Go如何解析不定JSON數(shù)據(jù),需要的朋友可以參考下
    2024-03-03
  • Golang中g(shù)orm無法將字段更新為空值

    Golang中g(shù)orm無法將字段更新為空值

    本文主要介紹了Golang中g(shù)orm無法將字段更新為空值,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Go中Writer和Reader接口的使用入門

    Go中Writer和Reader接口的使用入門

    本文主要介紹了Go中Writer和Reader接口的使用入門,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • go語言beego框架web開發(fā)語法筆記示例

    go語言beego框架web開發(fā)語法筆記示例

    這篇文章主要為大家介紹了go語言beego框架web開發(fā)語法筆記示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • Golang字符串的拼接方法匯總

    Golang字符串的拼接方法匯總

    字符串拼接在日常開發(fā)中是很常見的需求,今天我們來探討下如何用golang來實(shí)現(xiàn)字符串的拼接
    2018-10-10
  • go使用net/url包來解析URL提取主機(jī)部分

    go使用net/url包來解析URL提取主機(jī)部分

    這篇文章主要為大家介紹了go使用net/url包來解析URL提取主機(jī)部分實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • 詳解Golang如何優(yōu)雅判斷interface是否為nil

    詳解Golang如何優(yōu)雅判斷interface是否為nil

    這篇文章主要為大家詳細(xì)介紹了Golang如何優(yōu)雅判斷interface是否為nil的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解下
    2024-01-01
  • Golang斷言判斷值類型的實(shí)現(xiàn)方法

    Golang斷言判斷值類型的實(shí)現(xiàn)方法

    這篇文章主要介紹了Golang斷言判斷值類型的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Golang中文件目錄操作的實(shí)現(xiàn)步驟詳解

    Golang中文件目錄操作的實(shí)現(xiàn)步驟詳解

    在Golang中,文件目錄是指計(jì)算機(jī)文件系統(tǒng)中的文件夾或目錄。目錄是用于組織和存儲文件的一種方式,可以包含文件和其他子目錄,本文主要介紹了Golang中文件目錄操作的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2023-05-05
  • Golang解析yaml文件操作指南

    Golang解析yaml文件操作指南

    之前一直從事java開發(fā),習(xí)慣了使用yaml文件的格式,尤其是清晰的層次結(jié)構(gòu)、注釋,下面這篇文章主要給大家介紹了關(guān)于Golang解析yaml文件的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09

最新評論

凤阳县| 宝丰县| 阿尔山市| 溧水县| 台南市| 遂平县| 聂拉木县| 庄河市| 安吉县| 独山县| 丹巴县| 冕宁县| 施甸县| 东城区| 宁蒗| 平阳县| 益阳市| 始兴县| 冕宁县| 北宁市| 大兴区| 丹凤县| 凤翔县| 来凤县| 图木舒克市| 呼和浩特市| 海口市| 洛川县| 宁陵县| 固始县| 满城县| 浑源县| 昭平县| 醴陵市| 井陉县| 屯昌县| 扶余县| 新宾| 兴海县| 彭阳县| 双辽市|