Netty

ChannelInboundHandlerAdapter#channelRead 中若是經過 ChannelHandlerContext#writeAndFlush 發送多條消息的話,消息都是在處理完以後,一塊兒 flush 出去的。
若是想要實現每隔一段時間,發送一條消息這種需求的話,能夠另起一個 schdule 線程,定時去發送消息。線程

場景:接收到任務開始消息後,每隔2s上報一次任務狀態,上報10次後,發送一個任務結束消息
兩種方式實現:
1. 接收到任務開始消息後,啓一個 schdule 線程,每隔 2s 上報一次任務狀態,上報到第 10 次的時候,在任務狀態消息中打個任務結束標記
當客戶端接收到服務端處理任務狀態消息的回包後,發現任務結束標記後,就發送任務結束消息
注:這種方式要求客戶端和服務端在收發消息時將任務結束標記在一來一回的傳遞中原樣傳遞日誌

2. 接收到任務開始消息後,啓一個 schdule 線程,每隔 2s 上報一次任務狀態,上報到第 10 次的時候,發送任務結束消息netty

錯誤的作法1:在 ChannelHandler 線程中每隔 2s 上報一次消息,這樣消息會在最後一次才所有 flush。
錯誤的作法2:在 ChannelHandler 線程中啓一個 schdule 線程,每隔 2s 上報一次任務狀態。同時在 ChannelHandler 線程中監放任務狀態上報是否結束,沒有結束就 sleep,直到上報完成再發送任務結束消息
這兩種作法錯誤的緣由在於: ChannelHandler 線程在發送消息的過程當中阻塞了,因此全部的消息都是在整個邏輯處理完以後再 flush 出去的orm

排查netty錯誤時,能夠將 netty 的日誌開啓:
//記錄請求與響應報文
InternalLoggerFactory.setDefaultFactory(Slf4JLoggerFactory.INSTANCE);
pipeline.addAfter("idleEventHandler","loggingHandler",new LoggingHandler(LogLevel.INFO));blog

這樣就會獲得相似以下的日誌,這樣就能夠清楚的看到 netty wirte、read、flush的日誌了:
ip

 

推薦:
https://www.infoq.cn/article/netty-high-performance/get

相關文章
相關標籤/搜索