我真的很困惑老板组的线程数。我无法弄清楚我们需要多个老板线程的情况。在做,我们需要更多的比老板组单线程?Netty的创建者说,如果我们在不同的服务器引导程序之间共享NioEventLoopGroup,则多个老板线程很有用,但我不知道这样做的原因。
考虑以下简单的Echo服务器:
public class EchoServer { private final int port; private ListchannelFutures = new ArrayList (2); public EchoServer(int port) { this.port = port; } public void start() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(4); for (int i = 0; i != 2; ++i) { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) // the channel type .childHandler(new ChannelInitializer () { @Override public void initChannel(SocketChannel ch) throws Exception { System.out.println("Connection accepted by server"); ch.pipeline().addLast( new EchoServerHandler()); } }); // wait till binding to port completes ChannelFuture f = b.bind(port + i).sync(); channelFutures.add(f); System.out.println("Echo server started and listen on " + f.channel().localAddress()); } for (ChannelFuture f : channelFutures) f.channel().closeFuture().sync(); // close gracefully workerGroup.shutdownGracefully().sync(); bossGroup.shutdownGracefully().sync(); } public static void main(String[] args) throws Exception { if (args.length != 1) { System.err.println( "Usage: " + EchoServer.class.getSimpleName() + " "); return; } int port = Integer.parseInt(args[0]); new EchoServer(port).start(); }
在上面的示例中,我创建了一个具有1个线程的bossGroup和具有4个线程的workerGroup,并将这两个事件组共享到绑定到两个不同端口(例如9000和9001)的两个不同的引导程序。以下是我的处理程序:
@ChannelHandler.Sharable public class EchoServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf in = (ByteBuf) msg; System.out.println("Server received: " + in.toString(CharsetUtil.UTF_8) + " from channel " + ctx.channel().hashCode()); ctx.write(in); } @Override public void channelReadComplete(ChannelHandlerContext ctx) { System.out.println("Read complete for channel " + ctx.channel().hashCode()); // keep channel busy forever while(true); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } }
在上面的处理程序中,我故意通过while(true)来保持频道繁忙;现在,如果我使用参数9000启动我的应用程序,它将创建两个在端口9000和9001上绑定的服务器引导程序。
Echo server started and listen on /0:0:0:0:0:0:0:0:9090 Echo server started and listen on /0:0:0:0:0:0:0:0:9091
现在,如果我同时连接到两个端口并开始发送数据,则可以接收的最大连接数为4,这是有道理的,因为我创建了4个工作线程并保持它们的通道忙而不关闭它:
echo 'abc' > /dev/tcp/localhost/9000 echo 'def' > /dev/tcp/localhost/9000 echo 'ghi' > /dev/tcp/localhost/9001 echo 'jkl' > /dev/tcp/localhost/9000 echo 'mno' > /dev/tcp/localhost/9001 # will not get connected
您也可以:
telnet localhost 9000 -> then send data "abc" telnet localhost 9000 -> then send data "def" telnet localhost 9001 -> then send data "ghi" telnet localhost 9000 -> then send data "jkl" telnet localhost 9001 -> # will not get connected
我不明白的是,我有一个老板线程,并且能够通过两个服务器引导程序连接到两个端口。那么,为什么我们需要一个以上的老板线程(默认情况下,老板线程的数量为2 * num_logical_processors)?
谢谢,