netty4耗时业务处理实例
所属分类 netty
浏览量 1229
netty 4.0.16.Final
耗时业务不能放在IO线程处理,需要将耗时任务添加到业务线程池中执行
两种方式
Handler中加入线程池
Context中添加线程池
private static final NioEventLoopGroup bizpool = new NioEventLoopGroup(50);
pipeline.addLast(bizpool,new EchoServerHandler());
Handler中自定义业务线程池更加灵活,对于非耗时的任务可以直接在EventLoop线程中执行。
注意线程池的拒绝策略 ,如果使用 CallerRunsPolicy 可能会阻塞调用线程(IO 线程)
static final ThreadPoolExecutor pool =
new ThreadPoolExecutor(5, 20, 60L, TimeUnit.SECONDS,new SynchronousQueue());
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
// 直接提交到业务线程池执行
// 客户端 写入 和 服务端 响应顺序不一致时 ,可能会卡死 , 服务端 有 write, 但是客户端没响应
// 注意 一定要调用 writeAndFlush ,这要客户端才能收到消息
pool.submit(new Task(ctx, msg));
}
private static class Task implements Runnable {
private final Object msg;
final ChannelHandlerContext ctx;
public Task(ChannelHandlerContext ctx, Object msg) {
this.ctx = ctx;
this.msg = msg;
}
public void run() {
System.out.println("msg=" + msg);
System.out.println("msg.info=" + msg.getClass());
// 模拟耗时
CommUtil.doSleep(3000);
if ("bye".equals(msg.toString())) {
ctx.writeAndFlush(msg + "\n").addListener(ChannelFutureListener.CLOSE);
}else {
ctx.writeAndFlush(msg + "\n");
}
}
}
测试类
EchoClientTest 开多个线程 发数据
int bossThreads = 2;
int workerThreads = 1;
EventLoopGroup bossGroup = new NioEventLoopGroup(bossThreads);
EventLoopGroup workerGroup = new NioEventLoopGroup(workerThreads);
ServerBootstrap b = new ServerBootstrap();
b.option(ChannelOption.SO_BACKLOG, 1024);
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new EchoServerInit());
Channel ch = b.bind(port).sync().channel();
ch.closeFuture().sync();
workerThreads 为 1 ,只有一个IO线程,
如果不使用 业务线程池 ,直接在IO线程上执行耗时业务,业务操作只能串行执行
运行 EchoServer
mvn exec:java -Dexec.mainClass="dyyx.echo.EchoServer"
完整代码
https://gitee.com/dyyx/netty4demo/tree/master/src/main/java/dyyx/echo
https://gitee.com/dyyx/netty4demo/blob/master/src/main/java/dyyx/test/EchoClientTest.java
telnet 使用业务线程池的例子
https://gitee.com/dyyx/netty4demo/blob/master/src/main/java/dyyx/telnet/TelnetServerHandlerUseThreadPool.java
https://gitee.com/dyyx/netty4demo/blob/master/src/main/java/dyyx/telnetclient/TelnetClient.java
maven命令行运行main方法
上一篇
下一篇
springboot集成mybatis
spring-boot-starter原理
top使用技巧
netty性能优化点
netty ByteBuf 释放说明
eclipse使用用技巧