java - 使用 Netty 和 NIO 的高并发 HTTP

标签 java http concurrency clojure netty

我正在处理 example Netty HTTP Client code为了在并发的线程环境中发出 http 请求。

但是,我的系统在相当低的吞吐量下完全崩溃(有一系列异常)。

几乎是伪代码:

ClientBootstrap bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory()) 
bootstrap.setPipelineFactory(new HttpClientPipelineFactory());

ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
Channel channel = future.awaitUninterruptibly().getChannel();

HttpRequest request = new DefaultHttpRequest();
channel.write(request);

在示例中,为了发出请求,我创建了一个 ClientBootstrap,并从那里(通过几个环)创建了一个 Channel 来编写 HTTPRequest。

这一切都很好。

然而,在并发情况下,每个请求都应该经过相同的循环吗?我认为这就是目前对我来说最糟糕的事情。我应该重用连接还是以完全不同的方式构建我的客户端?

此外:我正在 Clojure 中执行此操作,如果这有什么不同的话。

最佳答案

不,你做对了。但是,您必须保留对 Channel 实例的引用。一旦你有了那个 channel ,只要它是打开的,你就不需要创建另一个 Bootstrap 。 (如果那是你正在做的。)

这是我在最近的项目中使用的:

类 ClientConnection (构造函数)

// Configure the client.
bootstrap = new ClientBootstrap(
    new NioClientSocketChannelFactory(
        Executors.newCachedThreadPool(),
        Executors.newCachedThreadPool()
    )
);

// Set up the pipeline factory.
bootstrap.setPipelineFactory(
    new ChannelPipelineFactory() {
        public ChannelPipeline getPipeline() throws Exception {
            return Channels.pipeline(
                // put your handlers here
            );
        }
    }
);

类 ClientConnection.connect(String host, int port)

if (isConnected()) {
    throw new IllegalStateException("already connected");
}

// Start the connection attempt.
ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));

channel = future.awaitUninterruptibly().getChannel();

// Wait until the connection is closed or the connection attempt fails.
channel.getCloseFuture().addListener(new ChannelFutureListener() {
    @Override
    public void operationComplete(ChannelFuture future) throws Exception {
        new Thread(new Runnable() {
            public void run() {
                // Shut down thread pools to exit
                // (cannot be executed in the same thread pool!
                bootstrap.releaseExternalResources();

                LOG.log(Level.INFO, "Shutting down");
            }
        }).start();
    }
});

所以,基本上,我只保留对 bootstrapchannel 的引用,但是在这些代码行之外几乎没有使用前者。

注意您应该只在应用程序退出时执行一次bootstrap.releaseExternalResources();。在我的例子中,客户端发送一些文件然后关闭 channel 并退出。

一旦你有一个连接的 Channel 实例,你只需要使用那个,直到你再次关闭它。关闭后,您可以调用bootstrap 再次创建一个新的Channel

个人觉得Netty一开始有点难懂,但是一旦掌握了它的工作原理,它简直就是Java中最好的NIO框架。海事组织。

关于java - 使用 Netty 和 NIO 的高并发 HTTP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5453602/

相关文章:

java - 在android中使用简单的java类进行Facebook native 登录

c# - ConcurrentDictionary 中的 Keys 集合是否是线程安全的

c - 并发进程的 FIFO 问题

java - 当我尝试倒计时时同步被阻塞

java - Play 框架 (1.2.5) - 是否可以在 Play 框架中持久保存二维数组?

java - 为什么 MockMvc 总是返回空的 content()?

java - 如何在图片/矩阵中递归旅行

http - 如何在 Puppet 文件资源中获取远程文件(例如从 Github)?

web-services - SOAP 与 HTTP

http - 浏览器何时刷新陈旧的缓存条目?