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

[备忘]netty 耗时任务,不要用eventLoop线程执行。

上一篇:[备忘]mybatis多数据源,xml文件扫描多个路径的写法
下一篇:[备忘]windows10子系统linux,Ubuntu更换root

添加日期:2021/4/21 22:01:52 快速返回   返回列表 阅读950次
参考:https://segmentfault.com/a/1190000008030772

static final EventExecutorGroup group = new DefaultEventExecutorGroup(16);
...

ChannelPipeline pipeline = ch.pipeline();

 pipeline.addLast("decoder", new MyProtocolDecoder());

 pipeline.addLast("encoder", new MyProtocolEncoder());

 // Tell the pipeline to run MyBusinessLogicHandler's event handler methods
 // in a different thread than an I/O thread so that the I/O thread is not blocked by
 // a time-consuming task.
 // If your business logic is fully asynchronous or finished very quickly, you don't
 // need to specify a group.
 pipeline.addLast(group, "handler", new MyBusinessLogicHandler());

其中EventExecutorGroup 就是专门来处理耗时业务的线程池。
======================================
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();

        这里创建了两个group, 我们提过这是boss线程组和worker线程组, 其实这两个线程组就相当于两个NioEventLoop的集合, 默认每个NioEventLoopGroup创建时, 如果不传入线程数, 会创建cpu核数*2个NioEventLoop线程,

其中boss线程通过轮询处理Server的accept事件, 而完成accept事件之后, 就会创建客户端channel, 通过一定的策略, 分发到worker线程进行处理, 而worker线程, 则主要用于处理客户端的读写事件

        除了轮询事件, EventLoop线程还维护了两个队列, 一个是延迟任务队列, 另一个是普通任务队列, 在进行事件轮询的同时, 如果队列中有任务需要执行则会去执行队列中的任务

        一个NioEventLoop绑定一个selector用于处理多个客户端channel, 但是一个客户端channel只能被一个NioEventLoop处理
========================================
一个NioEventLoop就是一个io线程,它负责读数据(异步的,系统主动通知),写数据(异步的),调用handler。

一个io线程,处理多个channel。如果某个channel的handler处理非常耗时,那么io线程就被占住了,无法及时处理其他channel了。

如果一个channel正在传送数据,另一个channel发来了完整消息,那么io线程是可以处理后者的,因为读数据是异步的,并不是io线程在那里傻等,而是系统收到数据后主动通知io线程的。
========================================
1.netty 中的 eventloop 就是线程的概念;

2. netty 中也没有I/O线程和用户线程的区分, 在编写netty程序时通常需要指定哪些eventloop执行哪些任务, boss eventloopgroup 对应 accept; worker eventloopgroup 对应 select/write/read 和 默认情况下的执行用户回调; 

另外如果指定第三个eventloopgroup, 那么用户回调就会放在这个线程组中执行, 本意是用于执行非执行不可的用户阻塞代码, 如果非要说那么这个线程组可以对应"用户线程", 但其实并不鼓励这样写;

3. 当没有指定第三个 eventloopgroup 时, 用户编写的事件响应回调代码 就是在 worker eventloop 中执行的, 也就是说 netty 的 worker eventloop 在处理完网络请求之后, 其回调依然在同一个线程中执行, 所以根本没有所谓的资源竞争问题;
========================================
注意,这个业务group线程池,要放到类变量里,做成static共享,别每次都new,那就死翘翘了。

一个channel,对应一个io线程,对应一个业务线程,对应一个handler。
netty都给绑定好了。
 

评论 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