为高请求量配置 Jetty

2022-09-02 01:28:28

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

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

我们的服务器在EC2中运行,具有8GB的RAM,其中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。

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


答案 1

首先,Jetty 7.0.0.pre5非常古老。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日志记录,以查看您遇到的问题是与jetty有关,还是与Java的GC有关。如果您通过 GC 日志记录看到有大规模的 GC“停止世界”事件需要花费大量时间,那么您就知道性能问题的另一个原因。


答案 2

推荐