Netty 3 & 4 workflow vs Nio Workflow
Netty 4 workflow vs Nio Workflow
Both boss and worker NioEventLoop
at io.netty.channel.nio.NioEventLoop.openSelector(NioEventLoop.java:126)
at io.netty.channel.nio.NioEventLoop.<init>(NioEventLoop.java:120)
at io.netty.channel.nio.NioEventLoopGroup.newChild(NioEventLoopGroup.java:87)
at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:57)
at io.netty.channel.MultithreadEventLoopGroup.<init>(MultithreadEventLoopGroup.java:49)
at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:61)
at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:52)
at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:44)
at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:36)
at io.netty.example.echo.EchoServer.run(EchoServer.java:43)
at io.netty.example.echo.EchoServer.main(EchoServer.java:78)
at io.netty.channel.socket.nio.NioServerSocketChannel.newSocket(NioServerSocketChannel.java:48)
at io.netty.channel.socket.nio.NioServerSocketChannel.<init>(NioServerSocketChannel.java:62)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at java.lang.Class.newInstance(Class.java:374)
at io.netty.bootstrap.AbstractBootstrap$BootstrapChannelFactory.newChannel(AbstractBootstrap.java:426)
at io.netty.bootstrap.AbstractBootstrap.initAndRegister(AbstractBootstrap.java:278)
at io.netty.bootstrap.AbstractBootstrap.doBind(AbstractBootstrap.java:260)
at io.netty.bootstrap.AbstractBootstrap.bind(AbstractBootstrap.java:256)
at io.netty.bootstrap.AbstractBootstrap.bind(AbstractBootstrap.java:231)
at io.netty.example.echo.EchoServer.run(EchoServer.java:60)
at io.netty.example.echo.EchoServer.main(EchoServer.java:78)
main thread start a boss thread
main@1, prio=5, in group 'main', status: 'RUNNING'
at java.lang.Thread.start(Thread.java:703)
at io.netty.util.concurrent.SingleThreadEventExecutor.startThread(SingleThreadEventExecutor.java:812)
at io.netty.util.concurrent.SingleThreadEventExecutor.execute(SingleThreadEventExecutor.java:690)
at io.netty.channel.AbstractChannel$AbstractUnsafe.register(AbstractChannel.java:414)
at io.netty.channel.SingleThreadEventLoop.register(SingleThreadEventLoop.java:60)
at io.netty.channel.MultithreadEventLoopGroup.register(MultithreadEventLoopGroup.java:69)
at io.netty.bootstrap.AbstractBootstrap.initAndRegister(AbstractBootstrap.java:287)
at io.netty.bootstrap.AbstractBootstrap.doBind(AbstractBootstrap.java:260)
at io.netty.bootstrap.AbstractBootstrap.bind(AbstractBootstrap.java:256)
at io.netty.bootstrap.AbstractBootstrap.bind(AbstractBootstrap.java:231)
at io.netty.example.echo.EchoServer.run(EchoServer.java:60)
at io.netty.example.echo.EchoServer.main(EchoServer.java:78)
then main thread put REGISTER task into taskQueue
main@1, prio=5, in group 'main', status: 'RUNNING'
at io.netty.util.concurrent.SingleThreadEventExecutor.addTask(SingleThreadEventExecutor.java:292)
at io.netty.util.concurrent.SingleThreadEventExecutor.execute(SingleThreadEventExecutor.java:691)
at io.netty.channel.AbstractChannel$AbstractUnsafe.register(AbstractChannel.java:414)
at io.netty.channel.SingleThreadEventLoop.register(SingleThreadEventLoop.java:60)
at io.netty.channel.MultithreadEventLoopGroup.register(MultithreadEventLoopGroup.java:69)
at io.netty.bootstrap.AbstractBootstrap.initAndRegister(AbstractBootstrap.java:287)
at io.netty.bootstrap.AbstractBootstrap.doBind(AbstractBootstrap.java:260)
at io.netty.bootstrap.AbstractBootstrap.bind(AbstractBootstrap.java:256)
at io.netty.bootstrap.AbstractBootstrap.bind(AbstractBootstrap.java:231)
at io.netty.example.echo.EchoServer.run(EchoServer.java:60)
at io.netty.example.echo.EchoServer.main(EchoServer.java:78)
boss thread poll it and do the real register
at io.netty.channel.nio.AbstractNioChannel.doRegister(AbstractNioChannel.java:282)
at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:438)
at io.netty.channel.AbstractChannel$AbstractUnsafe.access$100(AbstractChannel.java:373)
at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:417)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:354)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:349)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Thread.java:744)
at io.netty.channel.socket.nio.NioServerSocketChannel.doBind(NioServerSocketChannel.java:102)
at io.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:478)
at io.netty.channel.DefaultChannelPipeline$HeadHandler.bind(DefaultChannelPipeline.java:1000)
at io.netty.channel.DefaultChannelHandlerContext.invokeBind(DefaultChannelHandlerContext.java:456)
at io.netty.channel.DefaultChannelHandlerContext.bind(DefaultChannelHandlerContext.java:441)
at io.netty.channel.ChannelDuplexHandler.bind(ChannelDuplexHandler.java:38)
at io.netty.handler.logging.LoggingHandler.bind(LoggingHandler.java:254)
at io.netty.channel.DefaultChannelHandlerContext.invokeBind(DefaultChannelHandlerContext.java:456)
at io.netty.channel.DefaultChannelHandlerContext.bind(DefaultChannelHandlerContext.java:441)
at io.netty.channel.DefaultChannelPipeline.bind(DefaultChannelPipeline.java:842)
at io.netty.channel.AbstractChannel.bind(AbstractChannel.java:193)
at io.netty.bootstrap.AbstractBootstrap$2.run(AbstractBootstrap.java:321)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:354)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:348)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Thread.java:744)
this runnable task is from taskQueue
main@1, prio=5, in group 'main', status: 'RUNNING'
at io.netty.util.concurrent.SingleThreadEventExecutor.addTask(SingleThreadEventExecutor.java:292)
at io.netty.util.concurrent.SingleThreadEventExecutor.execute(SingleThreadEventExecutor.java:691)
at io.netty.util.concurrent.DefaultPromise.notifyListener(DefaultPromise.java:607)
at io.netty.util.concurrent.DefaultPromise.addListener(DefaultPromise.java:123)
at io.netty.channel.DefaultChannelPromise.addListener(DefaultChannelPromise.java:93)
at io.netty.channel.DefaultChannelPromise.addListener(DefaultChannelPromise.java:28)
at io.netty.bootstrap.AbstractBootstrap.doBind(AbstractBootstrap.java:266)
at io.netty.bootstrap.AbstractBootstrap.bind(AbstractBootstrap.java:256)
at io.netty.bootstrap.AbstractBootstrap.bind(AbstractBootstrap.java:231)
at io.netty.example.echo.EchoServer.run(EchoServer.java:60)
at io.netty.example.echo.EchoServer.main(EchoServer.java:78)
nioEventLoopGroup-2-1@1476, prio=10, in group 'main', status: 'RUNNING'
at io.netty.util.concurrent.SingleThreadEventExecutor.addTask(SingleThreadEventExecutor.java:292)
at io.netty.util.concurrent.SingleThreadEventExecutor.execute(SingleThreadEventExecutor.java:688)
at io.netty.channel.AbstractChannel$AbstractUnsafe.invokeLater(AbstractChannel.java:724)
at io.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:485)
at io.netty.channel.DefaultChannelPipeline$HeadHandler.bind(DefaultChannelPipeline.java:1000)
at io.netty.channel.DefaultChannelHandlerContext.invokeBind(DefaultChannelHandlerContext.java:456)
at io.netty.channel.DefaultChannelHandlerContext.bind(DefaultChannelHandlerContext.java:441)
at io.netty.channel.ChannelDuplexHandler.bind(ChannelDuplexHandler.java:38)
at io.netty.handler.logging.LoggingHandler.bind(LoggingHandler.java:254)
at io.netty.channel.DefaultChannelHandlerContext.invokeBind(DefaultChannelHandlerContext.java:456)
at io.netty.channel.DefaultChannelHandlerContext.bind(DefaultChannelHandlerContext.java:441)
at io.netty.channel.DefaultChannelPipeline.bind(DefaultChannelPipeline.java:842)
at io.netty.channel.AbstractChannel.bind(AbstractChannel.java:193)
at io.netty.bootstrap.AbstractBootstrap$2.run(AbstractBootstrap.java:321)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:354)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:348)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Thread.java:744)
at io.netty.channel.nio.AbstractNioChannel.doBeginRead(AbstractNioChannel.java:309)
at io.netty.channel.AbstractChannel$AbstractUnsafe.beginRead(AbstractChannel.java:613)
at io.netty.channel.DefaultChannelPipeline$HeadHandler.read(DefaultChannelPipeline.java:1028)
at io.netty.channel.DefaultChannelHandlerContext.invokeRead(DefaultChannelHandlerContext.java:618)
at io.netty.channel.DefaultChannelHandlerContext.read(DefaultChannelHandlerContext.java:599)
at io.netty.channel.DefaultChannelHandlerContext.read(DefaultChannelHandlerContext.java:28)
at io.netty.channel.ChannelDuplexHandler.read(ChannelDuplexHandler.java:95)
at io.netty.channel.DefaultChannelHandlerContext.invokeRead(DefaultChannelHandlerContext.java:618)
at io.netty.channel.DefaultChannelHandlerContext.read(DefaultChannelHandlerContext.java:599)
at io.netty.channel.DefaultChannelPipeline.read(DefaultChannelPipeline.java:872)
at io.netty.channel.AbstractChannel.read(AbstractChannel.java:223)
at io.netty.channel.DefaultChannelPipeline.fireChannelActive(DefaultChannelPipeline.java:759)
at io.netty.channel.AbstractChannel$AbstractUnsafe$2.run(AbstractChannel.java:488)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:354)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:348)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Thread.java:744)
boss thread loop
nioEventLoopGroup-2-1@1476, prio=10, in group 'main', status: 'RUNNING'
at io.netty.channel.socket.nio.NioServerSocketChannel.doReadMessages(NioServerSocketChannel.java:112)
at io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:71)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:478)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:447)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:341)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Thread.java:744)
boss thread fire a read event after accepted a client. ServerBootstrapAcceptor handle it , creating a new worker thread
nioEventLoopGroup-2-1@1252, prio=10, in group 'main', status: 'RUNNING'
at io.netty.util.concurrent.SingleThreadEventExecutor.startThread(SingleThreadEventExecutor.java:806)
at io.netty.util.concurrent.SingleThreadEventExecutor.execute(SingleThreadEventExecutor.java:690)
at io.netty.channel.AbstractChannel$AbstractUnsafe.register(AbstractChannel.java:414)
at io.netty.channel.SingleThreadEventLoop.register(SingleThreadEventLoop.java:60)
at io.netty.channel.SingleThreadEventLoop.register(SingleThreadEventLoop.java:48)
at io.netty.channel.MultithreadEventLoopGroup.register(MultithreadEventLoopGroup.java:64)
at io.netty.bootstrap.ServerBootstrap$ServerBootstrapAcceptor.channelRead(ServerBootstrap.java:249)
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337)
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323)
at io.netty.handler.logging.LoggingHandler.channelRead(LoggingHandler.java:297)
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337)
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785)
at io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:90)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:478)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:447)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:341)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Thread.java:744)
boss thread put the task into taskQueue, worker thread poll the task
nioEventLoopGroup-2-1@1476, prio=10, in group 'main', status: 'RUNNING'
at io.netty.util.concurrent.SingleThreadEventExecutor.addTask(SingleThreadEventExecutor.java:292)
at io.netty.util.concurrent.SingleThreadEventExecutor.execute(SingleThreadEventExecutor.java:691)
at io.netty.channel.AbstractChannel$AbstractUnsafe.register(AbstractChannel.java:414)
at io.netty.channel.SingleThreadEventLoop.register(SingleThreadEventLoop.java:60)
at io.netty.channel.SingleThreadEventLoop.register(SingleThreadEventLoop.java:48)
at io.netty.channel.MultithreadEventLoopGroup.register(MultithreadEventLoopGroup.java:64)
at io.netty.bootstrap.ServerBootstrap$ServerBootstrapAcceptor.channelRead(ServerBootstrap.java:249)
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337)
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323)
at io.netty.handler.logging.LoggingHandler.channelRead(LoggingHandler.java:297)
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337)
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785)
at io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe.read(AbstractNioMessageChannel.java:90)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:478)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:447)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:341)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Thread.java:744)
worker thread poll the task, and do the real register
nioEventLoopGroup-3-1@1751, prio=10, in group 'main', status: 'RUNNING'
at java.nio.channels.spi.AbstractSelectableChannel.register(AbstractSelectableChannel.java:193)
at io.netty.channel.nio.AbstractNioChannel.doRegister(AbstractNioChannel.java:285)
at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:438)
at io.netty.channel.AbstractChannel$AbstractUnsafe.access$100(AbstractChannel.java:373)
at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:417)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:354)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:348)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Thread.java:744)
nioEventLoopGroup-3-1@1751, prio=10, in group 'main', status: 'RUNNING'
at io.netty.channel.nio.AbstractNioChannel.doBeginRead(AbstractNioChannel.java:320)
at io.netty.channel.AbstractChannel$AbstractUnsafe.beginRead(AbstractChannel.java:613)
at io.netty.channel.DefaultChannelPipeline$HeadHandler.read(DefaultChannelPipeline.java:1028)
at io.netty.channel.DefaultChannelHandlerContext.invokeRead(DefaultChannelHandlerContext.java:618)
at io.netty.channel.DefaultChannelHandlerContext.read(DefaultChannelHandlerContext.java:599)
at io.netty.channel.DefaultChannelPipeline.read(DefaultChannelPipeline.java:872)
at io.netty.channel.AbstractChannel.read(AbstractChannel.java:223)
at io.netty.channel.DefaultChannelPipeline.fireChannelActive(DefaultChannelPipeline.java:759)
at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:443)
at io.netty.channel.AbstractChannel$AbstractUnsafe.access$100(AbstractChannel.java:373)
at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:417)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:354)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:348)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Thread.java:744)
nioEventLoopGroup-3-1@1751, prio=10, in group 'main', status: 'RUNNING'
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:291)
at io.netty.buffer.UnpooledUnsafeDirectByteBuf.setBytes(UnpooledUnsafeDirectByteBuf.java:401)
at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:869)
at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:208)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:87)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:478)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:447)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:341)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Thread.java:744)
After that, fire an event to worker io handler
nioEventLoopGroup-3-1@1751, prio=10, in group 'main', status: 'RUNNING'
at io.netty.example.echo.EchoServerHandler.channelRead(EchoServerHandler.java:36)
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337)
at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:100)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:478)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:447)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:341)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Thread.java:744)
####5. socketChannel.write(ByteBuffer byteBuffer) ####
nioEventLoopGroup-3-1@1751, prio=10, in group 'main', status: 'RUNNING'
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:3xx)
at io.netty.buffer.UnpooledUnsafeDirectByteBuf.getBytes(UnpooledUnsafeDirectByteBuf.java:381)
at io.netty.buffer.AbstractByteBuf.readBytes(AbstractByteBuf.java:717)
at io.netty.channel.socket.nio.NioSocketChannel.doWriteBytes(NioSocketChannel.java:214)
at io.netty.channel.nio.AbstractNioByteChannel.doWrite(AbstractNioByteChannel.java:178)
at io.netty.channel.socket.nio.NioSocketChannel.doWrite(NioSocketChannel.java:231)
at io.netty.channel.AbstractChannel$AbstractUnsafe.flush0(AbstractChannel.java:680)
at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.flush0(AbstractNioChannel.java:260)
at io.netty.channel.AbstractChannel$AbstractUnsafe.flush(AbstractChannel.java:649)
at io.netty.channel.DefaultChannelPipeline$HeadHandler.flush(DefaultChannelPipeline.java:1038)
at io.netty.channel.DefaultChannelHandlerContext.invokeFlush(DefaultChannelHandlerContext.java:674)
at io.netty.channel.DefaultChannelHandlerContext.flush(DefaultChannelHandlerContext.java:655)
at io.netty.example.echo.EchoServerHandler.channelReadComplete(EchoServerHandler.java:41)
at io.netty.channel.DefaultChannelHandlerContext.invokeChannelReadComplete(DefaultChannelHandlerContext.java:366)
at io.netty.channel.DefaultChannelHandlerContext.fireChannelReadComplete(DefaultChannelHandlerContext.java:348)
at io.netty.channel.DefaultChannelPipeline.fireChannelReadComplete(DefaultChannelPipeline.java:791)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:118)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:478)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:447)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:341)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:101)
at java.lang.Thread.run(Thread.java:744)
在netty4中, 一个SocketChannel应该对应一组pipeline chain. 如果pipeline chain里面某个handler逻辑比较耗时, 那最好把这种耗时的工作到到线程池里做。这叫做io任务与user任务分离。但这种分离会带来额外的context switch. 理想的情况是一个线程把io和user任务全部做完. 但user任务耜时长短不一, 使用这种方法会使某些user任务耗时长的线程一直很慢. 如果像netty4那样一个线程对应一个channel, 那么这个channel就一直很慢.
如果一个channel对应的这组 upstream io->user->down stream io 整个pipeline比较慢. 可以不可以让一个channel对应多组pipeline? 这样会造成GC问题?
Grizzly的Leader-Follower IO策略(见 https://grizzly.java.net/iostrategies.html), 就是upstream io->user->down stream io 全由一个线程处理, Channel如果还有io事件就转给别的线程处理。这样有效地减少了context switch, 但如果每次转的时候都需要实例化一组pipeline, 会带来GC问题。如果Channel共享pipeline, 用来减少GC, 这时候会有数据共享问题. 谁也无法保证用户不在某个Handler里存一些状态. 相反, 这就是netty4设计成一个Channel对应一组pipeline的原因.
Netty 3 workflow vs Nio Workflow
main@1, prio=5, in group 'main', status: 'RUNNING'
at java.nio.channels.Selector.open(Selector.java:227)
at org.jboss.netty.channel.socket.nio.SelectorUtil.open(SelectorUtil.java:63)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.openSelector(AbstractNioSelector.java:341)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.<init>(AbstractNioSelector.java:100)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.<init>(AbstractNioWorker.java:52)
at org.jboss.netty.channel.socket.nio.NioWorker.<init>(NioWorker.java:45)
at org.jboss.netty.channel.socket.nio.NioWorkerPool.createWorker(NioWorkerPool.java:45)
at org.jboss.netty.channel.socket.nio.NioWorkerPool.createWorker(NioWorkerPool.java:28)
at org.jboss.netty.channel.socket.nio.AbstractNioWorkerPool.newWorker(AbstractNioWorkerPool.java:143)
at org.jboss.netty.channel.socket.nio.AbstractNioWorkerPool.init(AbstractNioWorkerPool.java:81)
at org.jboss.netty.channel.socket.nio.NioWorkerPool.<init>(NioWorkerPool.java:39)
at org.jboss.netty.channel.socket.nio.NioWorkerPool.<init>(NioWorkerPool.java:33)
at org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory.<init>(NioServerSocketChannelFactory.java:149)
at org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory.<init>(NioServerSocketChannelFactory.java:131)
at org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory.<init>(NioServerSocketChannelFactory.java:115)
at org.jboss.netty.example.echo.EchoServer.run(EchoServer.java:40)
at org.jboss.netty.example.echo.EchoServer.main(EchoServer.java:63)
main@1, prio=5, in group 'main', status: 'RUNNING'
at java.nio.channels.ServerSocketChannel.open(ServerSocketChannel.java:105)
at org.jboss.netty.channel.socket.nio.NioServerSocketChannel.<init>(NioServerSocketChannel.java:55)
at org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory.newChannel(NioServerSocketChannelFactory.java:205)
at org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory.newChannel(NioServerSocketChannelFactory.java:85)
at org.jboss.netty.bootstrap.ServerBootstrap.bindAsync(ServerBootstrap.java:329)
at org.jboss.netty.bootstrap.ServerBootstrap.bind(ServerBootstrap.java:266)
at org.jboss.netty.example.echo.EchoServer.run(EchoServer.java:53)
at org.jboss.netty.example.echo.EchoServer.main(EchoServer.java:63)
New I/O server boss #17@646, prio=5, in group 'main', status: 'RUNNING'
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:203)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at org.jboss.netty.channel.socket.nio.NioServerBoss$RegisterTask.run(NioServerBoss.java:193)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.processTaskQueue(AbstractNioSelector.java:372)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:296)
at org.jboss.netty.channel.socket.nio.NioServerBoss.run(NioServerBoss.java:42)
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
New I/O worker #16@639, prio=5, in group 'main', status: 'RUNNING'
at sun.nio.ch.EPollArrayWrapper.epollWait(EPollArrayWrapper.java:-1)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:79)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:87)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:98)
at org.jboss.netty.channel.socket.nio.SelectorUtil.select(SelectorUtil.java:68)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.select(AbstractNioSelector.java:415)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:212)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
New I/O worker #15@638, prio=5, in group 'main', status: 'RUNNING'
at sun.nio.ch.EPollArrayWrapper.epollWait(EPollArrayWrapper.java:-1)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:79)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:87)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:98)
at org.jboss.netty.channel.socket.nio.SelectorUtil.select(SelectorUtil.java:68)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.select(AbstractNioSelector.java:415)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:212)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
... workers
New I/O worker #1@593, prio=5, in group 'main', status: 'RUNNING'
at sun.nio.ch.EPollArrayWrapper.epollWait(EPollArrayWrapper.java:-1)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:79)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:87)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:98)
at org.jboss.netty.channel.socket.nio.SelectorUtil.select(SelectorUtil.java:68)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.select(AbstractNioSelector.java:415)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:212)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Signal Dispatcher@533 daemon, prio=9, in group 'system', status: 'RUNNING'
Finalizer@534 daemon, prio=8, in group 'system', status: 'WAIT'
at java.lang.Object.wait(Object.java:-1)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:135)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:151)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:189)
Reference Handler@535 daemon, prio=10, in group 'system', status: 'WAIT'
at java.lang.Object.wait(Object.java:-1)
at java.lang.Object.wait(Object.java:503)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:133)
main@1, prio=5, in group 'main', status: 'RUNNING'
at java.util.Arrays.copyOf(Arrays.java:2271)
at java.util.zip.ZipCoder.getBytes(ZipCoder.java:89)
at java.util.zip.ZipFile.getEntry(ZipFile.java:306)
at java.util.jar.JarFile.getEntry(JarFile.java:226)
at java.util.jar.JarFile.getJarEntry(JarFile.java:209)
at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:840)
at sun.misc.URLClassPath.getResource(URLClassPath.java:199)
at java.net.URLClassLoader$1.run(URLClassLoader.java:358)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(AccessController.java:-1)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at org.jboss.netty.bootstrap.ServerBootstrap$Binder.channelOpen(ServerBootstrap.java:382)
at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:86)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559)
at org.jboss.netty.channel.Channels.fireChannelOpen(Channels.java:170)
at org.jboss.netty.channel.socket.nio.NioServerSocketChannel.<init>(NioServerSocketChannel.java:78)
at org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory.newChannel(NioServerSocketChannelFactory.java:205)
at org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory.newChannel(NioServerSocketChannelFactory.java:85)
at org.jboss.netty.bootstrap.ServerBootstrap.bindAsync(ServerBootstrap.java:329)
at org.jboss.netty.bootstrap.ServerBootstrap.bind(ServerBootstrap.java:266)
at org.jboss.netty.example.echo.EchoServer.run(EchoServer.java:53)
at org.jboss.netty.example.echo.EchoServer.main(EchoServer.java:63)
bind twice??
New I/O server boss #17@646, prio=5, in group 'main', status: 'RUNNING'
at java.nio.channels.spi.AbstractSelectableChannel.register(AbstractSelectableChannel.java:192)
at org.jboss.netty.channel.socket.nio.NioServerBoss$RegisterTask.run(NioServerBoss.java:198)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.processTaskQueue(AbstractNioSelector.java:372)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:296)
at org.jboss.netty.channel.socket.nio.NioServerBoss.run(NioServerBoss.java:42)
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
New I/O server boss #17@646, prio=5, in group 'main', status: 'RUNNING'
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:224)
at org.jboss.netty.channel.socket.nio.NioServerBoss.process(NioServerBoss.java:100)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:318)
at org.jboss.netty.channel.socket.nio.NioServerBoss.run(NioServerBoss.java:42)
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Accept n times??
New I/O worker #2@609, prio=5, in group 'main', status: 'RUNNING'
at java.nio.channels.spi.AbstractSelectableChannel.register(AbstractSelectableChannel.java:192)
at org.jboss.netty.channel.socket.nio.NioWorker$RegisterTask.run(NioWorker.java:151)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.processTaskQueue(AbstractNioSelector.java:372)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:296)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
New I/O worker #2@609, prio=5, in group 'main', status: 'RUNNING'
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:291)
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:64)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:108)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:318)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
####5. socketChannel.write(ByteBuffer byteBuffer) ####
New I/O worker #2@609, prio=5, in group 'main', status: 'RUNNING'
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471)
at org.jboss.netty.channel.socket.nio.SocketSendBufferPool$UnpooledSendBuffer.transferTo(SocketSendBufferPool.java:203)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.write0(AbstractNioWorker.java:201)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.writeFromUserCode(AbstractNioWorker.java:146)
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.handleAcceptedSocket(NioServerSocketPipelineSink.java:99)
at org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink.eventSunk(NioServerSocketPipelineSink.java:36)
at org.jboss.netty.channel.DefaultChannelPipeline.sendDownstream(DefaultChannelPipeline.java:574)
at org.jboss.netty.channel.Channels.write(Channels.java:704)
at org.jboss.netty.channel.Channels.write(Channels.java:671)
at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:248)
at org.jboss.netty.example.echo.EchoServerHandler.messageReceived(EchoServerHandler.java:47)
at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:108)
at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:318)
at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)
at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)