我正在处理 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();
}
});
所以,基本上,我只保留对 bootstrap
和 channel
的引用,但是在这些代码行之外几乎没有使用前者。
注意您应该只在应用程序退出时执行一次bootstrap.releaseExternalResources();
。在我的例子中,客户端发送一些文件然后关闭 channel 并退出。
一旦你有一个连接的 Channel
实例,你只需要使用那个,直到你再次关闭它。关闭后,您可以调用bootstrap
再次创建一个新的Channel
。
个人觉得Netty一开始有点难懂,但是一旦掌握了它的工作原理,它简直就是Java中最好的NIO框架。海事组织。
关于java - 使用 Netty 和 NIO 的高并发 HTTP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5453602/