22

在我们的应用程序中,我们需要处理每秒超过 5,000 个请求的请求量。我们被告知在我们的应用程序类型中使用 Jetty 是可行的(我们必须将 JSON-HTTP API 暴露给远程系统,然后它将启动入站请求和与我们的连接)。

我们收到数千个入站 HTTP 连接,每个连接都是持久的,持续大约 30 秒。然后,远程服务器会尽快向我们发出请求,因为我们可以在每个连接上响应它们。30 秒后连接关闭并打开另一个连接。我们必须在不到 100 毫秒(包括网络传输时间)内做出响应。

我们的服务器运行在具有 8GB RAM 的 EC2 中,其中 4GB 分配给我们的 Java VM(过去的研究建议您不应将超过一半的可用 RAM 分配给 JVM)。

以下是我们目前根据在网上阅读的各种提示初始化 Jetty 的方式:

Server server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(config.listenPort);
connector.setThreadPool(new QueuedThreadPool(5120));
connector.setMaxIdleTime(600000);
connector.setRequestBufferSize(10000);
server.setConnectors(new Connector[] { connector });
server.setHandler(this);
server.start();

请注意,我们的线程池中最初只有 512 个线程,我们尝试增加到 5120 但这并没有明显帮助。

我们发现使用这种设置,我们很难每秒处理 300 多个请求。我们认为问题不在于我们的处理程序,因为它只是在进行一些快速计算和 Gson 序列化/反序列化。

当我们在尝试处理此负载时手动执行自己的 HTTP 请求时,我们发现它可能需要几秒钟才能开始响应。

我们正在使用 Jetty 版本 7.0.0.pre5。

任何关于解决方案或隔离瓶颈的技术的建议都将不胜感激。

4

1 回答 1

29

首先,Jetty 7.0.0.pre5 已经老了。Jetty 9 现已推出,并进行了许多性能优化。

在https://www.eclipse.org/jetty/previousversions.html下载更新版本的 7.x 行

以下建议记录在

请务必阅读它们。

接下来,线程池大小用于处理接受的请求,512 为高。5120太可笑了。选择一个大于 50 和小于 500 的数字。

如果您有基于 Linux 的 EC2 节点,请确保配置网络以在操作系统级别获得最大收益。(详见上述列表中标题为“高负载”的文档)

确保您使用的是最新的 JRE/JDK,例如 Oracle Java 1.6u38 或 1.7u10。此外,如果您有 64 位操作系统,请使用 64 位 JRE/JDK。

将您的接受器计数SelectChannelConnector.setAcceptors(int)设置为介于 1 和 (number_of_cpu_cores - 1) 之间的值。

最后,设置优化的垃圾收集,并打开 GC Logging 以查看您遇到的问题是与码头有关,还是与 Java 的 GC 有关。如果您通过 GC 日志记录看到有大量的 GC“停止世界”事件需要花费大量时间,那么您就会知道导致性能问题的另一个原因。

于 2013-01-09T23:31:36.953 回答