可不可以重用eventloopgroup?
我把您的 run()method 稍加修改了一下,特别是现在只用了2个EventLoopGroup。 这是从《Netty In Action》这本书里受到的启发:
Suppose your server is processing a client request that requires it to act as a client to a third system. This can happen when an application, such as a proxy server, has to integrate with an organization’s existing systems, such as web services or databases. In such cases you’ll need to bootstrap a client Channel from a ServerChannel. You could create a new Bootstrap as described in section 8.2.1, but this is not the most efficient solution, as it would require you to define another EventLoop for the new client Channel. This would produce additional threads, necessitating context switching when exchanging data between the accepted Channel and the client Channel. A better solution is to share the EventLoop of the accepted Channel by passing it to the group() method of the Bootstrap. Because all Channels assigned to an EventLoop use the same thread, this avoids the extra thread creation and related context-switching mentioned previously.
================== 您觉得这样改合适吗? -- Babagilo
public void run(int port) throws InterruptedException, CertificateException, InvalidKeySpecException,
NoSuchAlgorithmException, NoSuchProviderException, IOException {
bossGroup = new NioEventLoopGroup(1);
workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 100)
//.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
BabagiloProxyHandler serverHandler = proxyMode == ProxyMode.TUNNEL
? new BabagiloProxyHandler(ch.eventLoop())
: new BabagiloProxyHandler(ch.eventLoop(), proxyInterceptInitializer,
proxyConfig, httpProxyExceptionHandle, serverPrivateKey, issuer, ca_private_key,
caNotBefore, caNotAfter, serverPubKey);
ch.pipeline().addLast("httpCodec", new HttpServerCodec());
ch.pipeline().addLast("serverHandle", serverHandler);
}
});
// Start the server
ChannelFuture f = b.bind(port).sync();
// Wait until the server socket is closed
//System.err.format("BabagiloProxy is listening at localhost:%d; Mode: %s%n", port, this.proxyMode);
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
已经重用了呀,你指的是哪里要重用
你除了bossGroup 和 workerGroup之外,还有第三个eventLoopGroup,是在 serverConfig.setProxyLoopGroup(new NioEventLoopGroup(serverConfig.getProxyGroupThreads())); 这一行被instantiated。
我的重构后的code里,没有用到这第三个eventLoopGroup,而是用 new BabagiloProxyHandler(ch.eventLoop())。。。。 将assign给client <-- > proxy 通道的eventLoop 传给了后面的 proxy <-->origin 通道来共用
谢谢, Babagilo
这个我之前也是这样复用的,后来不记得是碰到个什么问题才把proxy的eventLoop独立出来使用。。
这样子我就不知道该不该改了。。。
可能是我之前proxy connect->origin 用的同步写法,导致connect阻塞的时候线程被占用后续的客户端连接就全被阻塞住了,后来改成异步写法应该就不会有这个问题,代码是这部分:
cf = bootstrap.connect(host, port);
cf.addListener((ChannelFutureListener) future -> {
if (future.isSuccess()) {
future.channel().writeAndFlush(msg);
synchronized (requestList) {
requestList.forEach(obj -> future.channel().writeAndFlush(obj));
requestList.clear();
isConnect = true;
}
} else {
requestList.forEach(obj -> ReferenceCountUtil.release(obj));
requestList.clear();
future.channel().close();
channel.close();
}