合並批量請求


  前一段時間,碰到一個問題,后端提供的API是批量接口,允許在一個HTTP請求中放上N個業務上的請求,一起處理,完成后一起返回,但是我們的前端又是以單個請求為主,這樣勢必導致很多http請求僅僅包含單個業務請求,大量的把帶寬浪費在http head,以及把cpu浪費在http協議的解析上,而改寫現有代碼讓請求盡量合並在起來是一件既費力又會遭遇多線程間無法合並等問題的麻煩事情。。。那么,這里就需要找到一個不需要大幅修改現有的代碼,並且能完成請求合並的方法。

  軟件上的問題,大部分可以通過添加一個層來搞定,這次的這個問題也不例外。

  首先,來確定一下范圍,為了簡化問題,我們做了下面幾個限制:

  • 只支持該請求有一個類似TRequest[]的參數,並且其返回值為類似TResponse[],乍一看,好像很多請求不能滿足這個要求,不過,我們可以將其他參數放在Tuple之類的對象中,把請求偽裝成一個類型的數組
  • 只支持一個請求有且必須有一個返回,也就是說,不能一個請求返回多個結果,也不可以不返回結果
  • 只支持請求的順序與返回的順序一致,換句話說,請求1、2、3,必須返回1、2、3,順序必須一致。很多api不會這么設計,不過,我們可以加一些預處理,使這個條件滿足

  然后,需要分析一下合並策略:

  • 不是所有請求都能合並在一起的,這取決於后端API的實現,例如:不同權限角色可能不能合並,部分參數可能必須是一致的
  • 批量請求通常會有數量上限,不太可能有后端代碼會支持無限數量的批量
  • 合並請求往往是以增加延遲為代價的,如何在兩者之間平衡是一門藝術,也就是說無法說哪種方式是最好的,只能憑感覺

  這里,我們做了這樣的一個選擇:

  • 合並需要一些規則做約束,這些規則可以添加很多,但是必須是輕量級的,否則會影響合並的效率(這里我們只能假設,萬一真的有人在里面寫個Thread.Sleep,我們也只能呵呵了)
  • 延遲和合並之間的平衡,我們決定讓鏈接數來決定,也就是保持總鏈接數不大於某個值,如果鏈接很空閑,就直接出去,不做任何合並,反之,如果鏈接已經被占滿,就嘗試與排隊中的請求合並,無法合並,就新建請求
  • 不支持排隊中的請求再排序,這里假定所有請求都是相同優先級的

  到這里,我們的目標已經明確,剩下的就是寫代碼實現了。

----------------------------此處省去過程5000字------------------------------

  最后,分享一下這段代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM