我们刚刚构建了一个将数据存储到磁盘的服务器,并使用Netty进行了前端。在负载测试期间,我们看到Netty扩展到每秒大约8,000条消息。考虑到我们的系统,这看起来非常低。作为基准测试,我们编写了一个Tomcat前端并运行相同的负载测试。通过这些测试,我们每秒收到大约25,000条消息。
以下是我们的负载试验机的规格:
以下是Netty的负载测试设置:
以下是Tomcat的负载测试设置:
我的主要问题是,为什么性能会有如此大的差异?关于Netty,有什么明显的东西可以让它跑得比Tomcat快吗?
编辑:这是主要的Netty服务器代码:
NioServerSocketChannelFactory factory = new NioServerSocketChannelFactory();
ServerBootstrap server = new ServerBootstrap(factory);
server.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() {
RequestDecoder decoder = injector.getInstance(RequestDecoder.class);
ContentStoreChannelHandler handler = injector.getInstance(ContentStoreChannelHandler.class);
return Channels.pipeline(decoder, handler);
}
});
server.setOption("child.tcpNoDelay", true);
server.setOption("child.keepAlive", true);
Channel channel = server.bind(new InetSocketAddress(port));
allChannels.add(channel);
我们的处理程序如下所示:
public class RequestDecoder extends FrameDecoder {
@Override
protected ChannelBuffer decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) {
if (buffer.readableBytes() < 4) {
return null;
}
buffer.markReaderIndex();
int length = buffer.readInt();
if (buffer.readableBytes() < length) {
buffer.resetReaderIndex();
return null;
}
return buffer;
}
}
public class ContentStoreChannelHandler extends SimpleChannelHandler {
private final RequestHandler handler;
@Inject
public ContentStoreChannelHandler(RequestHandler handler) {
this.handler = handler;
}
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
ChannelBuffer in = (ChannelBuffer) e.getMessage();
in.readerIndex(4);
ChannelBuffer out = ChannelBuffers.dynamicBuffer(512);
out.writerIndex(8); // Skip the length and status code
boolean success = handler.handle(new ChannelBufferInputStream(in), new ChannelBufferOutputStream(out), new NettyErrorStream(out));
if (success) {
out.setInt(0, out.writerIndex() - 8); // length
out.setInt(4, 0); // Status
}
Channels.write(e.getChannel(), out, e.getRemoteAddress());
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
Throwable throwable = e.getCause();
ChannelBuffer out = ChannelBuffers.dynamicBuffer(8);
out.writeInt(0); // Length
out.writeInt(Errors.generalException.getCode()); // status
Channels.write(ctx, e.getFuture(), out);
}
@Override
public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) {
NettyContentStoreServer.allChannels.add(e.getChannel());
}
}
更新:
我已经设法将我的Netty解决方案控制在4000/s以内。几周前,我在连接池中测试客户端PING,作为对空闲套接字的安全防护,但在开始负载测试之前,我忘了删除该代码。每次从池(使用Commons池)签出套接字时,该代码都会有效地ping服务器。我把代码注释掉了,我现在用Netty得到了21000/秒,用Tomcat得到了25000/秒。
虽然,这对Netty来说是个好消息,但我在Netty上的速度仍然比Tomcat低4000/秒。如果有人有兴趣看到,我可以发布我的客户端(我认为我已经排除了,但显然没有)。
方法messageReceived是使用一个工作线程执行的,该工作线程可能被RequestHandler#handle阻塞,该工作线程可能忙于执行一些输入/输出工作。您可以尝试向通道管道中添加一个OrderdMemoryAwareThreadPoolExecutor(推荐)来执行处理程序,或者尝试将处理程序工作分配给新的ThreadPoolExecutor,并将引用传递给套接字通道,以便稍后将响应写回客户端。前任。:
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
executor.submit(new Runnable() {
processHandlerAndRespond(e);
});
}
private void processHandlerAndRespond(MessageEvent e) {
ChannelBuffer in = (ChannelBuffer) e.getMessage();
in.readerIndex(4);
ChannelBuffer out = ChannelBuffers.dynamicBuffer(512);
out.writerIndex(8); // Skip the length and status code
boolean success = handler.handle(new ChannelBufferInputStream(in), new ChannelBufferOutputStream(out), new NettyErrorStream(out));
if (success) {
out.setInt(0, out.writerIndex() - 8); // length
out.setInt(4, 0); // Status
}
Channels.write(e.getChannel(), out, e.getRemoteAddress());
}
问题内容: 我目前正在开始新的应用开发。应用程序设计师坚持认为我们使用 JBoss5 是因为它“更好”。是否有人对“更好”有更广泛的定义(如果如此)? 我有在具有大量用户负载的大规模应用程序中使用 Tomcat5 和6的经验,并且它处理得很好(IMHO)。两者都将在相同的硬件条件下(如果实现很重要)在 RedHat6 上运行。 提前致谢 问题答案: 说任何工具或框架都只是“更好”是可笑的。它总是取
我正在运行一个spring boot WebFlux应用程序,通常该应用程序运行在Netty嵌入式服务器之上。相反,我正在运行一个tomcat实例,我试图从我的pom中排除tomcat,但仍然遇到同样的问题。 所以我想通过运行Netty而不是Tomcat来解决这个问题。 这是我的pom依赖项:
Netty是一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。 也就是说,Netty 是一个基于NIO的客户、服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发
在深入研究我的问题时,解释了atg gRpc在netty失败中使用SunPKCS11进行TLS客户端身份验证,我更改了netty-tcnative-boringssl的版本。我房子里的罐子。Gradle来自 到 导致: +---io.netty:netty-tcnative-boringssl-static:+->2.0.1.final 之所以这样做,是因为根据Netty的javadoc方法也适用
在阅读了一些关于如何在使用Webflux时摆脱Tomcat的文章之后,我仍然无法使用Netty作为Tomcat的替代品。 因为这是一个涉及不同模块的项目,有一个父pom等。我将在这里发布repo的链接:https://github.com/deviad/clarity 让我知道如果有更多的文件等,你想让我复制粘贴在这里,以便遵守这样的政策。 我感兴趣的模块是clarity-transaction-
问题内容: 尽管我的业务逻辑没有问题,但事实证明我没有使用Netty 。更新要使用的测试代码后,我遇到了IllegalReferenceCountException的无尽循环。我承认对Netty还是陌生的,但这并不能证明在手动分配和释放资源的日子里回来。创建GC就是为了避免这种混乱。迪斯科,有人吗?那贝尔底呢? 我不断得到: 问题答案: 工作代码: 该代码可能更简洁一些,但是适用于Spring b