本文介绍了使用 Netty 和 NIO 的高并发 HTTP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理 示例 Netty HTTP 客户端代码 以便在并发的线程环境中发出 http 请求.

I am working through the example Netty HTTP Client code in order to make http requests within a concurrent, threaded environment.

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

However, my system breaks completely (with a slew of exceptions) at fairly low throughput.

几乎是伪代码:

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.

In the example, to make a request I create a ClientBootstrap, and from there (through a few hoops) a Channel to write the HTTPRequest.

这一切都有效并且很好.

This all works and is good.

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

However, in a concurrent situation, should every request be going through the same hoops? I think that is what's breaking things for me at the moment. Should I be reusing the connection or structuring my client in an entirely different way?

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

Also: I am doing this in Clojure, if that makes any difference at all.

推荐答案

不,您做对了.但是,您必须保留对 Channel 实例的引用.一旦拥有该通道,只要它处于打开状态,就不需要创建另一个引导程序.(如果这就是你正在做的事情.)

No, you're doing things right. You must, however, keep a reference to your Channel instance. Once you have that channel, as long as it is open, you don't need to create another bootstrap. (If that's what you're doing.)

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

This is what I used in a recent project :

class 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
            );
        }
    }
);

class 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 的引用,但是在这些代码行之外几乎不使用前者.

So, basically, I only keep a reference to bootstrap and channel, however the former is pretty much not used outside of these lines of code.

注意:你应该只在应用程序退出时执行一次bootstrap.releaseExternalResources();.就我而言,客户端发送一些文件,然后关闭频道并退出.

Note: you should only execute bootstrap.releaseExternalResources(); once, when the application is exiting. In my case, the client sends some files then close the channel and exit.

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

Once you have a connected Channel instance, you need only to use that one until you close it again. Once it is closed, you can recall the bootstrap to create a new Channel again.

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

Personally, I find Netty a little bit hard to understand at first, but once you grasp how it works, it is simply the best NIO framework in Java. IMO.

这篇关于使用 Netty 和 NIO 的高并发 HTTP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-16 21:10
查看更多