使用Netty

时间:2018-02-02 19:19:14

标签: multithreading concurrency netty

我正在调整基本的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个,但我没有看到我期望的并发性。我做错了什么。

2 个答案:

答案 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