超極速優(yōu)化:網(wǎng)絡(luò)開發(fā)中的請求合并!
今天,xjjdog來分享網(wǎng)絡(luò)開發(fā)中的一個超級技巧。它可以把兩個請求合并為一個請求,使得服務(wù)在弱網(wǎng)環(huán)境中性能得到極大的改善。
說開了很容易,但卻很難想到。
需求
如果我有大量的物聯(lián)網(wǎng)設(shè)備,比如說100萬臺。如果這些設(shè)備平均每10秒產(chǎn)生一個請求,那么QPS就是10W,這對于任何公司來說都是一個不小的規(guī)模了。
涉及到交易等有變更的需求,為了實(shí)現(xiàn)冪等操作,通常會提前申請一個交易號(或者說token),來進(jìn)行唯一的交易請求。
這樣,完成一個交易,需要至少發(fā)起兩個請求。一個是申請token,一個是拿著token做交易。
雖然說生成token很快,但它是從網(wǎng)絡(luò)上傳輸?shù)?。且不說現(xiàn)在都是異步模型,就拿網(wǎng)絡(luò)延遲來說,就是一個大的問題。它可能硬生生的把服務(wù)質(zhì)量給降了下去,增加了不確定性,也增加了編碼的復(fù)雜性。
有什么辦法來加快這個過程嗎?
從HTTP中學(xué)習(xí)經(jīng)驗
大多數(shù)人都知道,TCP有三次握手和四次揮手的機(jī)制。這種冗長的對話雖然保證了連接的可靠性,但卻損失了不少性能。HTTP從一到三各個版本,都是在盡量減少HTTP連接的個數(shù),也在減少交互的次數(shù)。
在比較早的HTTP1.0實(shí)現(xiàn)中,如果需要從服務(wù)端獲取大量資源,會開啟N條TCP短鏈接,并行的獲取信息。但由于TCP的三次握手和四次揮手機(jī)制,在連接數(shù)量增加的時候,整體的代價就變得比較大
在HTTP/1.1中,通過復(fù)用長連接,來改善這個情況,但問題是,由于TCP的消息確認(rèn)機(jī)制和順序機(jī)制以及流量控制策略的原因,資源獲取必須要排隊使用。一個請求,需要等待另外一個請求傳輸完畢,才能開始
HTTP/2采用多路復(fù)用,多個資源可以共用一個連接。但它解決的只是應(yīng)用層的復(fù)用,在TCP的傳輸上依然是阻塞的,后面的資源需要等待前面的傳輸完畢才能繼續(xù)。這就是隊頭阻塞現(xiàn)象(Head-of-line blocking)
QUIC,也就是HTTP3,抽象出了一個stream(流)的概念,多個流,可以復(fù)用一條連接,那么滑動窗口這些概念就不用作用在連接上了,而是作用在stream上。由于UDP只管發(fā)送不管成功與否的特性,這些數(shù)據(jù)包的傳輸就能夠并發(fā)執(zhí)行。協(xié)議的server端,會解析并緩存這些數(shù)據(jù)包,進(jìn)行組裝和整理等。由于抽象出了stream的概念,就使得某個數(shù)據(jù)包傳輸失敗,只會影響單個stream的準(zhǔn)確性,而不是整個連接的準(zhǔn)確性。
請求黏貼
其實(shí),我們參考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,然后發(fā)起下個請求。
通過這個方法,就可以把兩個請求合并為1個請求,完成我們的優(yōu)化目標(biāo)。
End
在網(wǎng)絡(luò)編程中,減少網(wǎng)絡(luò)交互是一個非常重要的優(yōu)化,尤其是在弱網(wǎng)環(huán)境中。雖然這個技巧很簡單,但它很難被想到。優(yōu)化效果也是巨大的,畢竟減少了一次網(wǎng)絡(luò)交互。
它有一個響亮的名字,那就是三連環(huán)。意味著前后請求的銜接,永不斷環(huán)。
作者簡介:小姐姐味道 (xjjdog),一個不允許程序員走彎路的公眾號。聚焦基礎(chǔ)架構(gòu)和Linux。十年架構(gòu),日百億流量,與你探討高并發(fā)世界,給你不一樣的味道。