Netty消息接收类故障案例分析

本文由《Netty 进阶之路》作者李林锋分析Netty消息接收类故障案例,涵盖服务端接收不到车载终端消息、MQTT服务拒绝接入、HTTP消息被多次读取等问题,提供故障定位及防挂死策略。建议Netty使用者了解故障定位技巧,避免业务使用不当导致的问题。
摘要由CSDN通过智能技术生成

《Netty 进阶之路》、《分布式服务框架原理与实践》作者李林锋深入剖析Netty消息接收类故障案例。李林锋此后还将在 InfoQ 上开设 Netty 专题持续出稿,感兴趣的同学可以持续关注。

1. 背景

1.1 消息接收类故障

尽管Netty应用广泛,非常成熟,但是由于对Netty底层机制不太了解,用户在实际使用中还是会经常遇到各种问题,大部分问题都是业务使用不当导致的。Netty使用者需要学习Netty的故障定位技巧,以便出了问题能够独立、快速的解决。

在各种故障中,Netty服务端接收不到客户端消息是一种比较常见的异常,大部分场景下都是用户使用不当导致的,下面我们对常见的消息接收接类故障进行分析和总结。

1.2 消息接收类故障定位技巧

如果业务的ChannelHandler接收不到消息,可能的原因如下:

  1. 业务的解码ChannelHandler存在BUG,导致消息解码失败,没有投递到后端。

  2. 业务发送的是畸形或者错误码流(例如长度错误),导致业务解码ChannelHandler无法正确解码出业务消息。

  3. 业务ChannelHandler执行了一些耗时或者阻塞操作,导致Netty的NioEventLoop被挂住,无法读取消息。

  4. 执行业务ChannelHandler的线程池队列积压,导致新接收的消息在排队,没有得到及时处理。

  5. 对方确实没有发送消息。

定位策略如下:

  1. 在业务的首个ChannelHandler的channelRead方法中打断点调试,看是否读取到消息。

  2. 在ChannelHandler中添加LoggingHandler,打印接口日志。

  3. 查看NioEventLoop线程状态,看是否发生了阻塞。

  4. 通过tcpdump抓包看消息是否发送成功。

2. 服务端接收不到车载终端消息

2.1 业务场景

车联网服务端使用Netty构建,接收车载终端的请求消息,然后下发给后端其它系统,最后返回应答给车载终端。系统运行一段时间后发现服务端接收不到车载终端消息,导致业务中断,需要尽快定位出问题原因。

2.2 故障现象

服务端运行一段时间之后,发现无法接收到车载终端的消息,相关日志示例如下:

\"\"

图1 车联网服务端无法接收消息日志

从日志看,服务端每隔一段时间(示例中是15秒,实际业务时间是随机的)就会接收不到消息,隔一段时间之后恢复,然后又没消息,周而复始。跟车载终端确认,终端设备每隔固定周期就会发送消息给服务端(日志分析),因此排除是终端没发消息导致的问题。怀疑是不是服务端负载过重,抢占不到CPU资源导致的周期性阻塞,采集CPU使用率,发现CPU资源不是瓶颈,排除CPU占用率高问题。

排除CPU之后,怀疑是不是内存有问题,导致频繁GC引起业务线程暂停。采集GC统计数据,示例如下:

\"\"

图2 GC数据采集

通过CPU和内存资源占用监控分析,发现硬件资源不是瓶颈,问题应该出在服务端代码侧。

2.3 故障分析

从现象上看,服务端接收不到消息,排除GC、网络等问题之后,很有可能是Netty的NioEventLoop线程阻塞,导致TCP缓冲区的数据没有及时读取,故障期间采集服务端的线程堆栈进行分析,示例如下:

\"\"
\"\"

图3 故障期间服务端线程堆栈

从线程堆栈分析,Netty的NioEventLoop读取到消息后,调用业务线程池执行业务逻辑时,发生了RejectedExecutionException异常,由于后续业务逻辑由NioEventLo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值