我真的很困惑老闆組的線程數量。我無法弄清楚我們需要多個boss線程的場景。在do we need more than a single thread for boss group? Netty的創建者說,如果我們在不同的服務器引導程序之間共享NioEventLoopGroup,那麼多個Boss線程是有用的,但我沒有看到它的原因。爲什麼我們真的需要多個netty boss線程?
考慮這個簡單的回聲服務器:
public class EchoServer {
private final int port;
private List<ChannelFuture> channelFutures = new ArrayList<ChannelFuture>(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<SocketChannel>() {
@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() +
" <port>");
return;
}
int port = Integer.parseInt(args[0]);
new EchoServer(port).start();
}
在上面的示例中,創建了1個線程和workerGroup與4個線程一個bossGroup和共享結合兩個不同的端口都事件組以兩種不同的自舉(例如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
我做什麼不明白的是,我有一個老闆線程,我可以用兩個服務器引導程序連接到兩個端口。那麼爲什麼我們需要多個boss線程(並且默認情況下,#boss線程是2 * num_logical_processors)?
感謝,
如果答案有幫助,請將其標記爲已接受。 – Suvitruf