netty vs jetty

对比版本netty4.1 , jetty9.3

1.socket连接处理

   jetty 使用AbstractConnector.Acceptor来处理连接, 线程数=Math.max(1, Math.min(4,cores/8)), 但是自己不new线程而是从共享的QueuedThreadPool中拿线程来执行

   netty 使用一个单独的NioEventLoopGroup来处理。 NioEventLoopGroup是一个Selector线程池, 其中每个NioEventLoop都表示一个Selector线程。 

         默认会初始化(cores*2)个NioEventLoop, 但是绑定一个端口只会使用一个NioEventLoop来处理该端口的所有连接

2.IO读写

  jetty 新来的SocketChannel会分配(SelectorManager.chooseSelector)一个ManagedSelector来监听IO数据(ManagedSelector.SelectorProducer.produce), 

        同时创建一个EndPoint对象来具体读写数据. 

        具体是通过SelectChannelEndPoint.fill读取IO数据,通过SelectChannelEndPoint.flush写入IO数据. 一个ManagedSelector内部有一个Selector实例可以注册多个SocketChannel,

  netty 使用一个单独的NioEventLoopGroup来处理, 新来的socketchannel根据一定的策略(GenericEventExecutorChooser or  

        PowerOfTowEventExecutorChooser)会分配一个NioEventLoop来处理IO读写并一直使用该NioEventLoop进行IO读写。 默认会初始化(cores*2)个NioEventLoop, 一个socketchannel的读写会在同一个NioEventLoop线程下处理

3.业务逻辑处理

  jetty 使用QueuedThreadPool 处理

  netty 需要用户自己实现线程池处理, 不推荐使用netty的IO读写线程池来处理业务逻辑

总结

  netty有一个处理客户端连接的线程池(parentGroup)(一般只会使用一个线程),一个处理IO读写的线程池(childGroup),同时需要用户自己实现一个处理业务逻辑的线程池

       Selector实例和线程是绑定在一起的表现为NioEventLoop, 也就是说一个NioEventLoop表示一个线程和一个Selector实例

  jetty有一个共享的线程池QueuedThreadPool,有一个共享的ManagedSelector(内部有一个Selector实例)池SelectorManager. 

       socket连接处理(长期占用死循环不退AbstractConnector.Acceptor.run),IO读写和业务逻辑处理共享同一个线程池QueuedThreadPool, 

       socket连接处理和IO读写共享同一个ManagedSelector池SelectorManager。默认 (cores+1/2)个ManagedSelector实例

猜你喜欢

转载自yuancihang.iteye.com/blog/2365215