我正在调整基本的Netty Discard服务器示例,以了解Netty如何处理来自同一个连接客户端的并发请求。我有以下处理程序....
private static class Handler extends SimpleChannelInboundHandler<String> {
@Override
protected void channelRead0(ChannelHandlerContext arg0, String arg1) throws Exception {
System.out.println("received " + arg1);
Thread.sleep(10000);
System.out.println("woke up");
}
}
服务器站起来如下......
public static void run() throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1); // (1)
EventLoopGroup workerGroup = new NioEventLoopGroup(3);
try {
ServerBootstrap b = new ServerBootstrap(); // (2)
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class) // (3)
.childHandler(new ChannelInitializer<SocketChannel>() { // (4)
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new Handler());
}
})
.option(ChannelOption.SO_BACKLOG, 128) // (5)
.childOption(ChannelOption.SO_KEEPALIVE, true); // (6)
// Bind and start to accept incoming connections.
ChannelFuture f = b.bind(4744).sync(); // (7)
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
服务器运行如此......
public static void main(String[] args) {
System.out.println("heere");
Executors.newSingleThreadExecutor().execute(() -> {
try {
run();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
} here
我的目标是看到Handler运行多个线程,由交织的“接收”和“唤醒”流量表示。我的印象是工作组是服务请求的线程,我已经分配了3个,但我没有看到我期望的并发性。我做错了什么。
答案 0 :(得分:1)
我只是快速运行你的代码,看到没有错。它可能与运行顺序和时间有关。所以我建议你改变我们的处理程序,如下所示。基本上,添加了线程名称,睡眠时间减少到1秒。请查看下面的示例输出,我可以看到所有3个线程同时处理不同的请求。
dtA=dtA[!(dtB$company %in% dtA$company)]
输出
dtA=dtA[dtB, on=date][!(company %in% comapny) & !(value %in% value)]
答案 1 :(得分:1)
您的Handler
阻塞了调用线程,这可能可以模拟繁重的工作负载(无论CPU使用率如何),但是Netty不应在其EventLoop
中运行长期任务,因为它们防止重用应该处理入站消息的线程。您的run()
方法正在阻止调用者(使用f.channel().closeFuture().sync()
)。调用方是main()
中的SingleThreadExecutor
方法。因此,您一次运行一台服务器,该服务器一次接受一个连接。
@Apolozeus的回答是正确的,因为减少睡眠延迟可以使您更接近Netty旨在支持的行为。
您要试验来自同一客户端的并发连接。除非您编写特定的代码,否则连接相同的客户端(从服务器的角度来看,相同的远程IP地址)还是连接的客户端都没关系。
就您多次运行服务器而言,您的代码很奇怪。这表明f.channel().closeFuture().sync()
是一个阻止呼叫。通过单个服务器将“睡眠任务”卸载到另一个执行程序,您可以使行为更接近实际应用程序。 “睡眠任务”还应该向客户端发送一些响应并关闭Channel
。