- 接收不到消息
如果業務的 ChannelHandler 接收不到消息,可能的原因如下:
1)業務的解碼 ChannelHandler 存在 BUG,導致消息解碼失敗,沒有投遞到後端;
2)業務發送的是畸形或者錯誤碼流(例如長度錯誤),導致業務解碼 ChannelHandler 無法正確解碼出業務消息;
3)業務 ChannelHandler 執行了一些耗時或者阻塞操作,導致 Netty 的 NioEventLoop 被掛住,無法讀取消息;
4)執行業務 ChannelHandler 的線程池隊列積壓,導致新接收的消息在排隊,沒有得到及時處理;
5)對方確實沒有發送消息。
定位策略如下:
1)在業務的首個 ChannelHandler 的 channelRead 方法中打斷點調試,看是否讀取到消息;
2)在 ChannelHandler 中添加 LoggingHandler,打印接口日誌;
3)查看 NioEventLoop 線程狀態,看是否發生了阻塞;
4)通過 tcpdump 抓包看消息是否發送成功。
- 內存泄露
通過 jmap -dump:format=b,file=xx pid 命令 Dump 內存堆棧,然後使用 MemoryAnalyzer 工具對內存佔用進行分析,查找內存泄漏點,然後結合代碼進行分析,定位內存泄漏的具體原因。
- 性能問題
如果出現性能問題,首先需要確認是 Netty 問題還是業務問題,通過 jstack 命令或者 jvisualvm 工具打印線程堆棧,按照線程 CPU 使用率進行排序(top -Hp 命令採集),看線程在忙什麼。
通常如果採集幾次都發現 Netty 的 NIO 線程堆棧停留在 select 操作上,說明 I/O 比較空閒,性能瓶頸不在 Netty,需要繼續分析看是否是後端的業務處理線程存在性能瓶頸。
如果發現性能瓶頸在網絡 I/O 讀寫上,可以適當調大 NioEventLoopGroup 中的 work I/O 線程數,直到 I/O 處理性能能夠滿足業務需求。