日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

网络通信优化之通信协议:如何优化RPC网络通信?

發(fā)布時間:2023/12/16 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网络通信优化之通信协议:如何优化RPC网络通信? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

RPC 通信是大型服務(wù)框架的核心
我們經(jīng)常討論微服務(wù),首要應(yīng)該了解的就是微服務(wù)的核心到底是什么,這樣我們在做技術(shù)選型時,才能更準確地把握需求。

就我個人理解,我認為微服務(wù)的核心是遠程通信和服務(wù)治理。遠程通信提供了服務(wù)之間通信的橋梁,服務(wù)治理則提供了服務(wù)的后勤保障。所以,我們在做技術(shù)選型時,更多要考慮的是這兩個核心的需求。

服務(wù)的拆分增加了通信的成本,特別是在一些搶購或者促銷的業(yè)務(wù)場景中,如果服務(wù)之間存在方法調(diào)用,比如,搶購成功之后需要調(diào)用訂單系統(tǒng)、支付系統(tǒng)、券包系統(tǒng)等,這種遠程通信就很容易成為系統(tǒng)的瓶頸。所以,在滿足一定的服務(wù)治理需求的前提下,對遠程通信的性能需求就是技術(shù)選型的主要影響因素。

目前,很多微服務(wù)框架中的服務(wù)通信是基于 RPC 通信實現(xiàn)的,在沒有進行組件擴展的前提下,SpringCloud 是基于 Feign 組件實現(xiàn)的 RPC 通信(基于 Http+Json 序列化實現(xiàn)), Dubbo 是基于 SPI 擴展了很多 RPC 通信框架,包括 RMI、Dubbo、Hessian 等 RPC 通信框架(默認是 Dubbo+Hessian 序列化)。不同的業(yè)務(wù)場景下,RPC 通信的選擇和優(yōu)化標準也不同。

我們部門在選擇微服務(wù)框架時,選擇了 Dubbo。當時的選擇標準就是RPC 通信可以支持搶購類的高并發(fā),在這個業(yè)務(wù)場景中,請求的特點是瞬時高峰、請求量大和傳入、傳出參數(shù)數(shù)據(jù)包較小。而 Dubbo 中的 Dubbo 協(xié)議就很好地支持了這個請求。

無論從響應(yīng)時間還是吞吐量上來看,單一 TCP 長連接+Protobuf 序列化實現(xiàn)的 RPC 通信框架都有著非常明顯的優(yōu)勢。

在高并發(fā)場景下,我們選擇后端服務(wù)框架或者中間件部門自行設(shè)計服務(wù)框架時,RPC 通信是重點優(yōu)化的對象。

什么是 RPC 通信
無論是微服務(wù)、SOA、還是 RPC 架構(gòu),它們都是分布式服務(wù)架構(gòu),都需要實現(xiàn)服務(wù)之間的互相通信,我們通常把這種通信統(tǒng)稱為 RPC 通信。

RPC(Remote Process Call),即遠程服務(wù)調(diào)用,是通過網(wǎng)絡(luò)請求遠程計算機程序服務(wù)的通信技術(shù)。RPC 框架封裝好了底層網(wǎng)絡(luò)通信、序列化等技術(shù),我們只需要在項目中引入各個服務(wù)的接口包,就可以實現(xiàn)在代碼中調(diào)用 RPC 服務(wù)同調(diào)用本地方法一樣。正因為這種方便、透明的遠程調(diào)用,RPC 被廣泛應(yīng)用于當下企業(yè)級以及互聯(lián)網(wǎng)項目中,是實現(xiàn)分布式系統(tǒng)的核心。

RMI(Remote Method Invocation)是 JDK 中最先實現(xiàn)了 RPC 通信的框架之一,RMI的實現(xiàn)對建立分布式 Java 應(yīng)用程序至關(guān)重要,是 Java 體系非常重要的底層技術(shù),很多開源的 RPC 通信框架也是基于 RMI 實現(xiàn)原理設(shè)計出來的,包括 Dubbo 框架中也接入了RMI 框架。接下來我們就一起了解下 RMI 的實現(xiàn)原理,看看它存在哪些性能瓶頸有待優(yōu)化。

RMI:JDK 自帶的 RPC 通信框架
目前 RMI 已經(jīng)很成熟地應(yīng)用在了 EJB 以及 Spring 框架中,是純 Java 網(wǎng)絡(luò)分布式應(yīng)用系統(tǒng)的核心解決方案。RMI 實現(xiàn)了一臺虛擬機應(yīng)用對遠程方法的調(diào)用可以同對本地方法的調(diào)用一樣,RMI 幫我們封裝好了其中關(guān)于遠程通信的內(nèi)容。

RMI 的實現(xiàn)原理
RMI 遠程代理對象是 RMI 中最核心的組件,除了對象本身所在的虛擬機,其它虛擬機也可以調(diào)用此對象的方法。而且這些虛擬機可以不在同一個主機上,通過遠程代理對象,遠程應(yīng)用可以用網(wǎng)絡(luò)協(xié)議與服務(wù)進行通信。

RMI 在高并發(fā)場景下的性能瓶頸
Java 默認序列化
RMI 的序列化采用的是 Java 默認的序列化方式,性能并不是很好,而且其它語言框架也暫時不支持 Java 序列化。

TCP 短連接
由于 RMI 是基于 TCP 短連接實現(xiàn),在高并發(fā)情況下,大量請求會帶來大量連接的創(chuàng)建和銷毀,這對于系統(tǒng)來說無疑是非常消耗性能的。

阻塞式網(wǎng)絡(luò) I/O
網(wǎng)絡(luò)通信存在 I/O 瓶頸,如果在 Socket 編程中使用傳統(tǒng)的 I/O 模型,在高并發(fā)場景下基于短連接實現(xiàn)的網(wǎng)絡(luò)通信就很容易產(chǎn)生 I/O 阻塞,性能將會大打折扣。

一個高并發(fā)場景下的 RPC 通信優(yōu)化路徑
SpringCloud 的 RPC 通信和 RMI 通信的性能瓶頸就非常相似。SpringCloud 是基于 Http通信協(xié)議(短連接)和 Json 序列化實現(xiàn)的,在高并發(fā)場景下并沒有優(yōu)勢。

RPC 通信包括了建立通信、實現(xiàn)報文、傳輸協(xié)議以及傳輸數(shù)據(jù)編解碼等操作,接下來我們就從每一層的優(yōu)化出發(fā),逐步實現(xiàn)整體的性能優(yōu)化。

  • 選擇合適的通信協(xié)議
    要實現(xiàn)不同機器間的網(wǎng)絡(luò)通信,我們先要了解計算機系統(tǒng)網(wǎng)絡(luò)通信的基本原理。網(wǎng)絡(luò)通信是兩臺設(shè)備之間實現(xiàn)數(shù)據(jù)流交換的過程,是基于網(wǎng)絡(luò)傳輸協(xié)議和傳輸數(shù)據(jù)的編解碼來實現(xiàn)的。其中網(wǎng)絡(luò)傳輸協(xié)議有 TCP、UDP 協(xié)議,這兩個協(xié)議都是基于 Socket 編程接口之上,為某類應(yīng)用場景而擴展出的傳輸協(xié)議。
  • 基于 TCP 協(xié)議實現(xiàn)的 Socket 通信是有連接的,而傳輸數(shù)據(jù)是要通過三次握手來實現(xiàn)數(shù)據(jù)傳輸?shù)目煽啃?#xff0c;且傳輸數(shù)據(jù)是沒有邊界的,采用的是字節(jié)流模式。

    基于 UDP 協(xié)議實現(xiàn)的 Socket 通信,客戶端不需要建立連接,只需要創(chuàng)建一個套接字發(fā)送數(shù)據(jù)報給服務(wù)端,這樣就不能保證數(shù)據(jù)報一定會達到服務(wù)端,所以在傳輸數(shù)據(jù)方面,基于UDP 協(xié)議實現(xiàn)的Socket 通信具有不可靠性。UDP 發(fā)送的數(shù)據(jù)采用的是數(shù)據(jù)報模式,每個UDP 的數(shù)據(jù)報都有一個長度,該長度將與數(shù)據(jù)一起發(fā)送到服務(wù)端。

    通過對比,我們可以得出優(yōu)化方法:為了保證數(shù)據(jù)傳輸?shù)目煽啃?#xff0c;通常情況下我們會采用TCP 協(xié)議。如果在局域網(wǎng)且對數(shù)據(jù)傳輸?shù)目煽啃詻]有要求的情況下,我們也可以考慮使用UDP 協(xié)議,畢竟這種協(xié)議的效率要比 TCP 協(xié)議高。

  • 使用單一長連接
    如果是基于 TCP 協(xié)議實現(xiàn) Socket 通信,我們還能做哪些優(yōu)化呢?
  • 服務(wù)之間的通信不同于客戶端與服務(wù)端之間的通信。客戶端與服務(wù)端由于客戶端數(shù)量多,基于短連接實現(xiàn)請求可以避免長時間地占用連接,導致系統(tǒng)資源浪費。

    但服務(wù)之間的通信,連接的消費端不會像客戶端那么多,但消費端向服務(wù)端請求的數(shù)量卻一樣多,我們基于長連接實現(xiàn),就可以省去大量的 TCP 建立和關(guān)閉連接的操作,從而減少系統(tǒng)的性能消耗,節(jié)省時間。

  • 優(yōu)化 Socket 通信
    建立兩臺機器的網(wǎng)絡(luò)通信,我們一般使用 Java 的 Socket 編程實現(xiàn)一個 TCP 連接。傳統(tǒng)的 Socket 通信主要存在 I/O 阻塞、線程模型缺陷以及內(nèi)存拷貝等問題。我們可以使用比較成 熟的通信框架,比如 Netty。Netty4 對 Socket 通信編程做了很多方面的優(yōu)化,具體見下方。
  • 實現(xiàn)非阻塞 I/O:多路復用器 Selector 實現(xiàn)了非阻塞 I/O 通信。
    高效的 Reactor 線程模型:Netty 使用了主從 Reactor 多線程模型,服務(wù)端接收客戶端請求連接是用了一個主線程,這個主線程用于客戶端的連接請求操作,一旦連接建立成功,將會監(jiān)聽 I/O 事件,監(jiān)聽到事件后會創(chuàng)建一個鏈路請求。

    鏈路請求將會注冊到負責 I/O 操作的 I/O 工作線程上,由 I/O 工作線程負責后續(xù)的 I/O 操作。利用這種線程模型,可以解決在高負載、高并發(fā)的情況下,由于單個 NIO 線程無法監(jiān)聽海量客戶端和滿足大量 I/O 操作造成的問題。

    串行設(shè)計:服務(wù)端在接收消息之后,存在著編碼、解碼、讀取和發(fā)送等鏈路操作。如果這些操作都是基于并行去實現(xiàn),無疑會導致嚴重的鎖競爭,進而導致系統(tǒng)的性能下降。為了提升性能,Netty 采用了串行無鎖化完成鏈路操作,Netty 提供了 Pipeline 實現(xiàn)鏈路的各個操作在運行期間不進行線程切換。

    零拷貝:一個數(shù)據(jù)從內(nèi)存發(fā)送到網(wǎng)絡(luò)中,存在著兩次拷貝動作,先是從用戶空間拷貝到內(nèi)核空間,再是從內(nèi)核空間拷貝到網(wǎng)絡(luò) I/O 中。而 NIO 提供的ByteBuffer 可以使用 Direct Buffers 模式,直接開辟一個非堆物理內(nèi)存,不需要進行字節(jié)緩沖區(qū)的二次拷貝,可以直接將數(shù)據(jù)寫入到內(nèi)核空間。

    除了以上這些優(yōu)化,我們還可以針對套接字編程提供的一些 TCP 參數(shù)配置項,提高網(wǎng)絡(luò)吞吐量,Netty 可以基于 ChannelOption 來設(shè)置這些參數(shù)。
    TCP_NODELAY:TCP_NODELAY 選項是用來控制是否開啟 Nagle 算法。Nagle 算法通過緩存的方式將小的數(shù)據(jù)包組成一個大的數(shù)據(jù)包,從而避免大量的小數(shù)據(jù)包發(fā)送阻塞網(wǎng)絡(luò),提高網(wǎng)絡(luò)傳輸?shù)男省N覀兛梢躁P(guān)閉該算法,優(yōu)化對于時延敏感的應(yīng)用場景。

    SO_RCVBUF 和 SO_SNDBUF:可以根據(jù)場景調(diào)整套接字發(fā)送緩沖區(qū)和接收緩沖區(qū)的大小。

    SO_BACKLOG:backlog 參數(shù)指定了客戶端連接請求緩沖隊列的大小。服務(wù)端處理客戶端連接請求是按順序處理的,所以同一時間只能處理一個客戶端連接,當有多個客戶端進來的時候,服務(wù)端就會將不能處理的客戶端連接請求放在隊列中等待處理。

    SO_KEEPALIVE:當設(shè)置該選項以后,連接會檢查長時間沒有發(fā)送數(shù)據(jù)的客戶端的連接狀態(tài),檢測到客戶端斷開連接后,服務(wù)端將回收該連接。我們可以將該時間設(shè)置得短一些,來提高回收連接的效率。

  • 量身定做報文格式
    接下來就是實現(xiàn)報文,我們需要設(shè)計一套報文,用于描述具體的校驗、操作、傳輸數(shù)據(jù)等內(nèi)容。為了提高傳輸?shù)男?#xff0c;我們可以根據(jù)自己的業(yè)務(wù)和架構(gòu)來考慮設(shè)計,盡量實現(xiàn)報體小、滿足功能、易解析等特性。

  • 編碼、解碼
    序列化編碼和解碼的過程,對于實現(xiàn)一個好的網(wǎng)絡(luò)通信協(xié)議來說, 兼容優(yōu)秀的序列化框架是非常重要的。如果只是單純的數(shù)據(jù)對象傳輸,我們可以選擇性能相對較好的 Protobuf 序列化,有利于提高網(wǎng)絡(luò)通信的性能。

  • 調(diào)整 Linux 的 TCP 參數(shù)設(shè)置選項
    如果 RPC 是基于 TCP 短連接實現(xiàn)的,我們可以通過修改 Linux TCP 配置項來優(yōu)化網(wǎng)絡(luò)通信。
    我們可以通過 sysctl -a | grep net.xxx 命令運行查看 Linux 系統(tǒng)默認的的 TCP 參數(shù)設(shè)置, 如果需要修改某項配置,可以通過編輯 vim/etc/sysctl.conf,加入需要修改的配置項, 并通過 sysctl -p 命令運行生效修改后的配置項設(shè)置。通常我們會通過修改以下幾個配置項來提高網(wǎng)絡(luò)吞吐量和降低延時。

  • 總結(jié)

    以上是生活随笔為你收集整理的网络通信优化之通信协议:如何优化RPC网络通信?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。