天天看點

超極速優化:網絡開發中的請求合并!

超極速優化:網絡開發中的請求合并!
原創:小姐姐味道(微信公衆号ID:xjjdog),歡迎分享,非公衆号轉載保留此聲明。

今天,xjjdog來分享網絡開發中的一個超級技巧。它可以把兩個請求合并為一個請求,使得服務在弱網環境中性能得到極大的改善。

說開了很容易,但卻很難想到。

需求

如果我有大量的物聯網裝置,比如說100萬台。如果這些裝置平均每10秒産生一個請求,那麼QPS就是10W,這對于任何公司來說都是一個不小的規模了。

涉及到交易等有變更的需求,為了實作幂等操作,通常會提前申請一個交易号(或者說token),來進行唯一的交易請求。

這樣,完成一個交易,需要至少發起兩個請求。一個是申請token,一個是拿着token做交易。

雖然說生成token很快,但它是從網絡上傳輸的。且不說現在都是異步模型,就拿網絡延遲來說,就是一個大的問題。它可能硬生生的把服務品質給降了下去,增加了不确定性,也增加了編碼的複雜性。

有什麼辦法來加快這個過程嗎?

從HTTP中學習經驗

大多數人都知道,TCP有三次握手和四次揮手的機制。這種冗長的對話雖然保證了連接配接的可靠性,但卻損失了不少性能。HTTP從一到三各個版本,都是在盡量減少HTTP連接配接的個數,也在減少互動的次數。

在比較早的HTTP1.0實作中,如果需要從服務端擷取大量資源,會開啟N條TCP短連結,并行的擷取資訊。但由于TCP的三次握手和四次揮手機制,在連接配接數量增加的時候,整體的代價就變得比較大

在HTTP/1.1中,通過複用長連接配接,來改善這個情況,但問題是,由于TCP的消息确認機制和順序機制以及流量控制政策的原因,資源擷取必須要排隊使用。一個請求,需要等待另外一個請求傳輸完畢,才能開始

HTTP/2采用多路複用,多個資源可以共用一個連接配接。但它解決的隻是應用層的複用,在TCP的傳輸上依然是阻塞的,後面的資源需要等待前面的傳輸完畢才能繼續。這就是​

​隊頭阻塞現象(Head-of-line blocking)​

QUIC,也就是HTTP3,抽象出了一個stream(流)的概念,多個流,可以複用一條連接配接,那麼滑動視窗這些概念就不用作用在連接配接上了,而是作用在stream上。由于UDP隻管發送不管成功與否的特性,這些資料包的傳輸就能夠并發執行。協定的server端,會解析并緩存這些資料包,進行組裝和整理等。由于抽象出了stream的概念,就使得某個資料包傳輸失敗,隻會影響單個stream的準确性,而不是整個連接配接的準确性。

請求黏貼

其實,我們參考TCP的三次握手就可以了。TCP的握手和揮手流程都差不多,但為什麼握手是三次,但揮手是四次呢?

原因就是TCP把SYN和ACK兩個封包,合并成一個傳回了。

超極速優化:網絡開發中的請求合并!

我們可以把token看作是序列号,然後把它黏貼在正常的請求裡傳回就可以了。

比如,原來的請求是。

一、擷取token

request: /getToken
response: 
{
    "token": "12345"
}
      

二、送出請求

request: /postOrder
{
    "token": "12345",
    "other": {}
}

response:
{
    "status": 200
}
      

合并後的請求是。

request: /postOrder
{
    "token": "12345",
    "other": {}
}

response:
{
    "status": 200,
    "token": "12346"
}
      

隻需要在每次請求傳回的時候,不論成功還是失敗,都附加一個新的token到用戶端。用戶端緩存這個token,然後發起下個請求。

通過這個方法,就可以把兩個請求合并為1個請求,完成我們的優化目标。

End

在網絡程式設計中,減少網絡互動是一個非常重要的優化,尤其是在弱網環境中。雖然這個技巧很簡單,但它很難被想到。優化效果也是巨大的,畢竟減少了一次網絡互動。

超極速優化:網絡開發中的請求合并!

它有一個響亮的名字,那就是三連環。意味着前後請求的銜接,永不斷環。

作者簡介:小姐姐味道  (xjjdog),一個不允許程式員走彎路的公衆号。聚焦基礎架構和Linux。十年架構,日百億流量,與你探讨高并發世界,給你不一樣的味道。

超極速優化:網絡開發中的請求合并!

繼續閱讀