天天看點

消息隊列面試解析 - 傳輸協定(下)2 雙工收發3 總結

2 雙工收發

2.1 單工通信

任一時刻,資料隻能單向傳輸,一個人說時,另一個人隻能聽。

HTTP 1.0協定就是這樣,用戶端與服務端建立個連接配接後,用戶端發個請求,直到服務端傳回響應或請求逾時,這段時間内,這個連接配接通道上不能再發其他請求。

這種單工通信,效率低,很多浏覽器和APP為解決性能問題,隻能同時在服務端和用戶端間建立多條連接配接。

單工通信時,一句對一句,請求和響應按序依次收發,有個天然對應關系。就像被女朋友質問時,女朋友問一句,你才敢答一句。這溝通效率有何意義?

2.2 雙工通信

而TCP連接配接是全雙工通道,可同時進行資料的雙向收發,互不影響。要提高吞吐量,應用層協定必須支援雙工通信。

雙工通信,不管是用戶端還是服務端建立好連接配接後,雙方都能基于該socket進行收發消息,而不是伺服器隻能accept到message後才能做些處理。

如果說你和你對象有邊聽邊說的本事,換成雙工協定後,基本就是在和女人講道理,你們就會混亂到分不清到底在回答問題or陳述觀點。

并發下,順序也無法保證。實際設計協定時,一般不關心順序,隻需確定請求和響應能夠正确對應。

解決對應問題

發送請求時,給每個請求加個序号:該序号在本次會話内保證唯一,然後在響應中帶上請求的序号,這就能把請求和響應對應上。

加上序号後,即使如搶答一般混亂,也分得清到底在說啥。

你和你對象就能對自己發出去的請求來編号,回複對方響應的時候,帶上對方請求的編号即可。這就解決了雙工通信的主要問題。

在一次會話過程中,開頭的先是唯一序列号嗎?然後後面跟資料長度,再是内容嗎?

那接到消息的一方,如何分辨序列号的長度大小,做到區分序列号和内容前的資料長度資訊?

開頭就肯定是資料長度,序号也是資料的一部分!是以應該在資料長度的後面。

3 總結

設計傳輸協定時,隻要雙方應用程式能夠識别傳輸協定,互相交流即可,并沒啥絕對的規範。

首要得解決斷句,有“分隔符”和“前置長度”兩種斷句方案。

使用ID來辨別請求與響應對應關系的方法,是比較通用的實作雙工通信的方法,可有效提升資料傳輸的吞吐量。

解決了斷句,實作了雙工通信,配合專用序列化方法,即可實作高性能的網絡通信協定,實作高性能的程序間通信。很多MQ、RPC架構都是用這種方式來實作它們自己的私有應用層傳輸協定。

簡單的高性能通信程式:你和你對象三組對話,服務端是你對象,用戶端是你自己,讓倆人在客廳碰見一百萬次,記錄下總共耗時。

https://github.com/WangYangA9/netty-FullDuplex-example https://sourcegraph.com/github.com/swgithub1006/mqlearning/-/tree/src/main/java/org/coffee/mqlearning