合併批量請求

  前一段時間,碰到一個問題,後端提供的API是批量接口,容許在一個HTTP請求中放上N個業務上的請求,一塊兒處理,完成後一塊兒返回,可是咱們的前端又是以單個請求爲主,這樣勢必致使不少http請求僅僅包含單個業務請求,大量的把帶寬浪費在http head,以及把cpu浪費在http協議的解析上,而改寫現有代碼讓請求儘可能合併在起來是一件既費力又會遭遇多線程間沒法合併等問題的麻煩事情。。。那麼,這裏就須要找到一個不須要大幅修改現有的代碼,而且能完成請求合併的方法。前端

  軟件上的問題,大部分能夠經過添加一個層來搞定,此次的這個問題也不例外。git

  首先,來肯定一下範圍,爲了簡化問題,咱們作了下面幾個限制:github

  • 只支持該請求有一個相似TRequest[]的參數,而且其返回值爲相似TResponse[],乍一看,好像不少請求不能知足這個要求,不過,咱們能夠將其餘參數放在Tuple之類的對象中,把請求假裝成一個類型的數組
  • 只支持一個請求有且必須有一個返回,也就是說,不能一個請求返回多個結果,也不能夠不返回結果
  • 只支持請求的順序與返回的順序一致,換句話說,請求一、二、3,必須返回一、二、3,順序必須一致。不少api不會這麼設計,不過,咱們能夠加一些預處理,使這個條件知足

  而後,須要分析一下合併策略:後端

  • 不是全部請求都能合併在一塊兒的,這取決於後端API的實現,例如:不一樣權限角色可能不能合併,部分參數可能必須是一致的
  • 批量請求一般會有數量上限,不太可能有後端代碼會支持無限數量的批量
  • 合併請求每每是以增長延遲爲代價的,如何在二者之間平衡是一門藝術,也就是說沒法說哪一種方式是最好的,只能憑感受

  這裏,咱們作了這樣的一個選擇:api

  • 合併須要一些規則作約束,這些規則能夠添加不少,可是必須是輕量級的,不然會影響合併的效率(這裏咱們只能假設,萬一真的有人在裏面寫個Thread.Sleep,咱們也只能呵呵了)
  • 延遲和合並之間的平衡,咱們決定讓連接數來決定,也就是保持總連接數不大於某個值,若是連接很空閒,就直接出去,不作任何合併,反之,若是連接已經被佔滿,就嘗試與排隊中的請求合併,沒法合併,就新建請求
  • 不支持排隊中的請求再排序,這裏假定全部請求都是相同優先級的

  到這裏,咱們的目標已經明確,剩下的就是寫代碼實現了。數組

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

  最後,分享一下這段代碼線程

相關文章
相關標籤/搜索