[心缘地方]同学录
首页 | 功能说明 | 站长通知 | 最近更新 | 编码查看转换 | 代码下载 | 常见问题及讨论 | 《深入解析ASP核心技术》 | 王小鸭自动发工资条VBA版
登录系统:用户名: 密码: 如果要讨论问题,请先注册。

[备忘]netty,业务处理耗时,导致心跳无法下发的问题。

上一篇:[备忘]netty的write和Flush方法是线程安全的。
下一篇:[转帖]谈谈CSMA/CD,TCP中的二进制指数退避算法

添加日期:2021/5/11 18:53:21 快速返回   返回列表 阅读788次
现状:
心跳是单向的,Server给client发送ping,后者回一个ping,完事。

现象:
client经常收不到心跳,导致断线重连。

分析:
p.addLast(new bizHandler());
代码中是这样写的,没有指定executor,那么默认使用IO线程。
假设有8个IO线程,1万个channel,那么这1万个channel会分别绑定到某个IO线程上。
一个channel的所有读写操作,都由某个IO线程处理。

该IO线程持有一个无界队列,所有读写操作都会封装为一个TASK,放入该队列,由线程依次执行。
如果某个TASK很耗时,那么后面的TASK都要等待。
心跳包,是一个write操作,也会进入该队列,傻等……

解决办法:
需要将心跳包独立出来,使用独立的线程池。
新写一个inbound的Handler,实现超时处理方法,发心跳。

// 业务线程
static final EventExecutorGroup bizGroup = new DefaultEventExecutorGroup(Runtime.getRuntime().availableProcessors() * 2);

p.addLast(new 心跳Handler());
p.addLast(bizGroup,new bizHandler());

心跳Handler放前面,使用IO线程。
业务Handler放后面,使用业务线程。
哦了……

超时后,netty会往后找第一个inbound的Hander,调用其中的处理方法。
我看了两天源代码,才分析出来的。
-----------------------------------
如果不用netty的线程池,使用JDK的线程池,那么要注意,
要在解包完毕后,得到完整消息后,再扔给线程池处理。
写消息时,也注意,要write完整的消息,否则可能会有并发写入的问题,导致消息数据错乱。


 

评论 COMMENTS
没有评论 No Comments.

添加评论 Add new comment.
昵称 Name:
评论内容 Comment:
验证码(不区分大小写)
Validation Code:
(not case sensitive)
看不清?点这里换一张!(Change it here!)
 
评论由管理员查看后才能显示。the comment will be showed after it is checked by admin.
CopyRight © 心缘地方 2005-2999. All Rights Reserved