10-Netty 高性能架构设计-任务队列(普通任务, 定时任务)
TaskQueue 任务队列
任务队列中的Task有三种典型使用场景
- 用户程序自定义的普通任务 [举例说明]
- 用户自定义定时任务
- 非当前Reactor线程调用Channel的各种方法
- 例如在推送系统的业务线程里面, 根据用户的标识, 找到对应的Channel引用,然后调用Write类方法向该用户推送消息, 就会进入到该场景,最终的write会提交到任务队列中后被异步消费
问题
如果在读取或者操作时碰到非常耗时的业务, 那么他就会阻塞在业务执行的地方,我们希望他可以异步执行,而不是阻塞事件, 我们可以提交到该Channel对应的NioEventLoop的taskQueue中
修改NettyServerHandler的ChannelRead方法
Thread.sleep(10 * 1000); ctx.writeAndFlush(Unpooled.copiedBuffer("Hello 客户端 我读取完成喽", StandardCharsets.UTF_8)); System.out.println("go on....");
这样测试,我们服务器端,channelRead方法就会阻塞10秒才返回
用户自定义普通任务
使用用户自定义普通任务解决
ctx.channel().eventLoop().execute(new Runnable() { @Override public void run() { try { Thread.sleep(10 * 1000); ctx.writeAndFlush(Unpooled.copiedBuffer("Hello 客户端 我读取完成喽", StandardCharsets.UTF_8)); } catch (InterruptedException e) { e.printStackTrace(); System.out.println("发生异常"); } } });
通过上下文对象获取Channel,获取EventLoop,并提交一个任务
测试可以,这样的话,ChannelRead事件不会阻塞,并且任务是在10秒后返回的
但是这里如果是多任务那么时间是累加的
// 应为是任务队列所以第一个任务返回是延迟10秒 ctx.channel().eventLoop().execute(new Runnable() { @Override public void run() { try { Thread.sleep(10 * 1000); ctx.writeAndFlush(Unpooled.copiedBuffer("Hello 客户端 我读取完成喽", StandardCharsets.UTF_8)); } catch (InterruptedException e) { e.printStackTrace(); System.out.println("发生异常"); } } }); // 第二个任务返回是 上面的 10 + 下面的 20 = 30 秒 ctx.channel().eventLoop().execute(new Runnable() { @Override public void run() { try { Thread.sleep(20 * 1000); ctx.writeAndFlush(Unpooled.copiedBuffer("Hello 客户端 我读取完成喽", StandardCharsets.UTF_8)); } catch (InterruptedException e) { e.printStackTrace(); System.out.println("发生异常"); } } });
用户自定义定时任务
// 用户自定义定时任务 ctx.channel().eventLoop().schedule(() -> { try { Thread.sleep(10 * 1000); ctx.writeAndFlush(Unpooled.copiedBuffer("Hello 客户端 我读取完成喽", StandardCharsets.UTF_8)); } catch (InterruptedException e) { e.printStackTrace(); System.out.println("发生异常"); } }, 5, TimeUnit.SECONDS);
延时5秒
执行测试 ok
那么普通任务和延时任务并存,那么他的执行时间如何呢?
经过测试一个普通任务10秒,一个定时任务5秒+执行10秒, 总共会在20秒执行完成,在10秒返回一个, 在20秒返回一个

预测普通任务和延时任务同时开始, 普通任务开始执行,延时任务开始倒计时,在延时任务倒计时5秒后进入等待,而普通任务10秒执行完成后延时任务直接开始执行,所以在20秒返回
方案再说明
- Netty抽象出两组线程池, BOSSGroup专门负责接收客户端连接, WorkerGroup专门负责网络读写操作
- NioEventLoop表示一个不断循环执行处理任务的线程, 每个NioEventLoop都有一个Selector, 用于监听绑定在其上的Socket网络通道
- NioEventLoop内部采用串行化设计, 从消息的读取->解码->处理->编码->发送,始终由IO线程NioEventLoop负责
- NioEventLoopGroup 下包含多个NioEventLoop
- 每个NioEventLoop中都包含一个Selector,和一个TaskQueue
- 每个NioEventLoop的selector上可以注册监听多个NioChannel
- 每个NioChannel只会绑定在唯一的NioEventLoop上
- 每个NioChannel都绑定有一个自己的ChannelPipeline
分类:
netty高性能网络框架
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
2021-01-21 SpringBoot之SpringBoot整合多环境不同配置文件
2021-01-21 SpringBoot之SpringBoot整合lombok
2021-01-21 SpringBoot之SpringBoot整合devtools热部署
2021-01-21 SpringBoot之SpringBoot整合Mybatis
2021-01-21 SpringBoot之SpringBoot整合JdbcTemplate
2021-01-21 SpringBoot之SpringBoot整合Thymeleaf模板引擎
2021-01-21 SpringBoot之SpringBoot整合Freemarker模板引擎