日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

Netty:遇到TCP發送緩沖區滿了 寫半包操作該如何處理

什么是寫半包

寫半包:一份數據,一次發送沒有把他全部發送,需要循環發送,那么第一次的操作稱為寫半包

什么情況下會出現寫半包:

發送方發送200byte,但是接收方只能接受100byte,因此發送方只會發送小于100byte的數據。

說到這里,機智的小伙伴已經想到了這跟TCP滑動窗口和消息中間件中常見的消息堆積是一個道理。

總的來說:接收方頂不住來自發送方的數據壓力

image.png 對?.NETty來說就是,這個時刻TCP發送緩沖區滿了,無法再接收整包數據,剩下的數據則會通過Channel去監聽寫操作,當觸發寫操作的時候,再把這部分數據給帶上,那么這部分數據才完整地傳輸。

Netty中的寫半包處理

前提知識:Netty中的網絡數據讀寫,都先經過ByteBuf image-20230227222618518

  • 讀操作:從ByteBuf中讀取數據
  • 寫操作:將數據寫入到ByteBuf,然后再通過其他方式把ByteBuf的數據寫入(#doWrite

Netty中的網路操作都是通過Channel和里面聚合的對象Unsafe對象進行操作,簡單介紹一下。

Channel

Channel的作用:給Netty用來進行網絡網絡

JDK 也有自己原生的Channel,但是為了方便框架擴展使用,Netty采用的是封裝了一層Facade(門面模式)。

最重要的是能夠支持Netty的自定義Channel來應對不同的業務場景。

Channel會被注冊到EventLoop上,在注冊的時候定義好感興趣的事件,他采用的是基于事件觸發的方式,當Channel上觸發相對應的事件時,就會主動回調通知,然后交給對應的ChannelHandler進行處理。

由于本篇講的是寫半包,因此不再過多解釋。

image.png

總的來說: Channel就是Netty用來處理網絡數據流的

回到本篇的主題:寫半包

AbstractNioByteChannel

主要負責處理寫半包

總的流程如圖:

image.png

ChannelOutboundBuffer:環形發送數組

  1. 不停地從ChannelOutboundBuffer讀取數據,看是否有可以發送的數據

  2. 如果有,并且是ByteBuf類型的,可以選擇發送數據

    • 如果一次發送沒有發送完,則采取一定次數的循環發送(寫半包)
  3. 數據最后還是沒有發送完,則會開一條新線程專門進行剩余數據的發送

  4. 在最后會去同步數據寫入進度

源碼解析 #doWrite

image-20230311150751449

不停地去環形發送數組里面取數據出來

  • 如果是空了,代表發送完了,把寫標志位置空(clearOpWrite

image-20230311150858669

如果不是空數據,則判斷是不是ByteBuf數據

  • 對其進行強轉,若可讀字節數是0,代表消息不可讀(reidIndex >= writeIndex),則把他在環形發送數組中移除

第一次讀的時候,會先去獲取循環發送次數writeSpinCount。循環發送次數就是指:第一次發送沒有完成時(寫半包)進行循環發送的次數。

給他設置一個閾值,為的就是當循環發送的時候,IO線程會一直嘗試寫操作,此時IO線程無法處理其他操作,相當于局部阻塞、死鎖、假死的情況

像這種處理手法非常常見,比如一般我們會給分布式鎖設置一個鎖的超時時間,除此之外還需要設置一個客戶端的超時時間,避免客戶端在拿到鎖的時候,這把鎖已經過期了。客戶端的超時時間會比鎖的超時時間要短

image-20230311151404816

然后就是進行循環發送了

image-20230311151426008

消息發送操作完成時候,會調用ChannelOutboundBuffer更新發送進度的消息,并且還會判斷是否需要寫半包處理

image-20230311151525404

如果沒有發完,則設置寫半包標識位,啟動專門的寫半包線程繼續發后續的消息

總結

寫半包問題本質上是:對于接收方來說,來自發送方的數據壓力太大了,因此不得不采取的一種降保護措施

可以在發送方進行解決、也可以在接收方進行解決

Netty并沒有采取說,遇到TCP緩沖區滿了之后,這個數據包就等下一次再等發,而是能發多少就發多少,不夠的 下次再發,是一種追求性能的選擇。

像消息中間件遇到消息堆積問題,在消接收方(消費者)增大消費的速度,比如:加消費隊列或擴充消費者群組等。

又或者限制發送方(生產者)的發送速度,比如TCP的滑動窗口。

所以互聯想的技術都是有相關聯的,能看到互相的影子。


 

分享到:
標簽:TCP
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定