首页  

netty4耗时业务处理实例     所属分类 netty 浏览量 1070
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<Runnable>());
		
	@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使用用技巧