一、簡介
Socket.D 是一種二進制字節(jié)流傳輸協(xié)議,位于 OSI 模型中的5~6層,底層可以依賴 TCP、UDP、KCP、WebSocket 等傳輸層協(xié)議。由 Noear 開發(fā)。支持異步流處理。其開發(fā)背后的動機是用開銷更少的協(xié)議取代超文本傳輸協(xié)議(HTTP),HTTP 協(xié)議對于許多任務(如微服務通信)來說效率低下。
二、設計目標
- 協(xié)議接口豐富,包括 Send, SendAsRequest, SendAndSubscribe,Reply,ReplyEnd
- 支持應用層流量控制
- 支持單連接雙向、多次復用
- 支持斷連后自動重連
- 可以更好的使用 WebSocket 協(xié)議
三、消息驅(qū)動
網(wǎng)絡通信是異步的,Socket.D 協(xié)議包含這一點,并將所有通信建模為在單個網(wǎng)絡連接(TCP)上的、多路復用的消息流,在等待響應時從不同步阻塞。
響應式宣言指出:
反應式系統(tǒng)依賴異步的消息傳遞,從而確保了松耦合、隔離、位置透明的組件之間有著明確邊界。 這一邊界還提供了將失敗作為消息委托出去的手段。 使用顯式的消息傳遞,可以通過在系統(tǒng)中塑造并監(jiān)視消息流隊列, 并在必要時應用回壓, 從而實現(xiàn)負載管理、 彈性以及流量控制。 使用位置透明的消息傳遞作為通信的手段, 使得跨集群或者在單個主機中使用相同的結(jié)構(gòu)成分和語義來管理失敗成為了可能。 非阻塞的通信使得接收者可以只在活動時才消耗資源, 從而減少系統(tǒng)開銷。
此外,HTTP/2 FAQ 很好地解釋了在持久連接上采用多路復用的面向消息的協(xié)議的動機:
-
HTTP/1.x 有一個叫做 “head-of-line blocking(隊頭阻塞)” 的問題,在這種情況下,即在一個連接上一次只能有一個未完成請求。
-
HTTP/1.1 試圖通過流水線(Pipelining)來解決這個問題,但它并沒有完全解決這個問題(大的或慢的響應仍然會阻塞后面的其他響應)。此外,人們發(fā)現(xiàn)流水線很難部署,因為許多代理和服務器不能正確地處理它。
在HTTP/1中使用并發(fā)連接和域名分片來緩解HOL問題 -
并發(fā)連接,瀏覽器針對每個源(域名)可以打開4-8個TCP連接,提升并發(fā)度。
-
域名分片,瀏覽器和HTTP/1限制了并發(fā)連接的數(shù)量,那么就把多個域名指向一臺服務器,從而提升連接數(shù)量。
這迫使客戶端使用一些啟發(fā)式方法(通常是猜測)來確定什么請求在什么時候放在與源站的哪個連接上;由于加載一個頁面的次數(shù)通常是可用連接數(shù)量的10倍或者更多。這會導致被阻塞的請求“瀑布式”的增長,從而嚴重的影響性能。
多路復用通過允許多個請求和響應消息在一個連接上同時傳輸來解決這些問題;甚至可以將一條消息的部分與另一條消息的部分混合在一起。
使用HTTP/1,瀏覽器為每個源打開4-8個連接,由于許多站點使用多個源,這可能意味著打開單個頁面要加載30多個TCP連接。
一個應用程序同時打開如此多的連接,打破了TCP所建立的許多假設;由于每個連接都會在響應中傳輸大量的數(shù)據(jù),因此TCP緩沖區(qū)很大可能會溢出,從而導致?lián)砣录统瑫r重傳。
一個應用程序同時打開如此多的連接,此外,使用如此多的連接不公平地壟斷了網(wǎng)絡資源,“竊取”了其他性能更好的應用程序(如VoIP)的資源。
四、協(xié)議交互模型
不合適的協(xié)議會增加系統(tǒng)開發(fā)的成本。它可能是一個不匹配的抽象,但是我們必須將系統(tǒng)設計強加到他允許的交互模型中。這迫使開發(fā)人員花費額外的時間來解決它的缺點,以處理錯誤并獲得可接受的性能。在多語言環(huán)境中,這個問題被放大了,因為不同的語言將使用不同的方法來解決這個問題,這需要團隊之間的額外協(xié)調(diào)。到目前為止,通信協(xié)議事實上的標準是HTTP,它只支持請求/響應的交互模式。在某些情況下,這可能不是最理想通信模型。
- Send(只管發(fā)送,不要結(jié)果)
發(fā)完就不管是請求/響應的優(yōu)化,在不需要響應時很有用。它允許顯著的性能優(yōu)化,不僅僅是通過跳過響應來節(jié)省網(wǎng)絡使用,而且還可以減少客戶端和服務器的處理時間,因為客戶端不需要記錄和等待請求關聯(lián)的響應和取消請求。
此交互模型對于支持有損的用例非常有用,例如非關鍵事件日志記錄、或者設備信息上報。
像這樣使用:
clientSession.send("/demo", entity);
- SendAsRquest(發(fā)送一個請求,并要求一個響應)
仍然支持標準請求/響應語義,并且仍有望代表 Socket.D 連接上的大多數(shù)請求。這些請求/響應交互可以被認為是優(yōu)化的“只有 1 個響應的流”,并且是在單個連接上多路復用的異步消息。
消費者“等待”響應消息,所以它看起來像一個典型的請求/響應,但它從不同步阻塞。
就像 http 一樣使用:
//同步等待
let response = clientSession.sendAndRequest("/demo", entity).await();
//異步回調(diào)
clientSession.sendAndRequest("/demo", entity).thenReply(response => {
});
- SendAndSubscribe(發(fā)送一個訂閱,可以接收多個答復)
從一個請求一個響應那兒延伸出來的是多個響應,它允許多條消息流回。將此視為“集合”或“列表”響應,但不是將所有數(shù)據(jù)作為單個響應返回,而是按順序流回每個元素。
用例可能包括以下內(nèi)容:獲取視頻列表,在目錄中獲取產(chǎn)品,逐行檢索文件。
可能有點像 mq,還可能通過 range 指定數(shù)據(jù)區(qū)間(或者不指定):
//異步回調(diào)
clientSession.sendAndSubscribe("/demo", entity.range(0,5)).thenReply(reply => {
if(reply.isEnd()){
//如果需要識別最后一個?
}else{
//
}
});
五、協(xié)議形式
- 連接上傳輸?shù)臄?shù)據(jù)可稱之為流,每個消息都會有一個 sid(流Id)
- 流(Stream)由幀(Frame)組成
- 幀(Frame)包含了流Id(Sid)、事件(Event)、元數(shù)據(jù)字符串(MetaString)及數(shù)據(jù)(Data)
幀碼結(jié)構(gòu)為:
[len:int][flag:int][sid:str(<64)][\n][event:str(<512)][\n][metaString:str(<4k)][\n][data:byte(<16m)]
Socket.D 是一個二進制協(xié)議,也就是說在一個 Socket.D 連接上傳輸?shù)南Ⅲw對數(shù)據(jù)格式?jīng)]有任何要求,應用程序可以為所欲為的壓縮數(shù)據(jù)量的大小。文章來源:http://www.zghlxwxcb.cn/news/detail-809362.html
這樣的二進制協(xié)議通常來說能給性能帶來極大的提升,但是產(chǎn)生的代價是,網(wǎng)絡中間件也會因為無法解讀消息體中的數(shù)據(jù),喪失了在對具體應用流量進行監(jiān)控,日志和路由的能力。Socket.D 通過把每個消息體分成 metaString 和 data 的方式,在保證高效傳輸?shù)那疤嵯拢峁┝吮┞渡倭吭獢?shù)據(jù)給網(wǎng)絡中間件的能力。文章來源地址http://www.zghlxwxcb.cn/news/detail-809362.html
- data 一般作為應用本身需要傳遞的業(yè)務數(shù)據(jù),采取自定義的高效序列化方式,且對網(wǎng)絡基礎設施不可見。
- metaString 采用標準的 urlQueryString 格式。在分布式傳輸?shù)倪^程中,這些中間件可以按需求對 metaString 進行讀寫,然后監(jiān)控應用健康狀況或者調(diào)整路由。
Socket.D 有哪些適用的場景?
- 移動設備與服務器的連接
- 數(shù)據(jù)雙向傳輸,且支持流量控制。
- 支持連接修復,比如手機進地鐵之后,網(wǎng)絡斷開一段時間,其他協(xié)議需要重新建立連接,Socket.D 會自動修復連接。
- 微服務場景
到了這里,關于新一代通信協(xié)議 - Socket.D的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!