gpt4 book ai didi

http - Jetty 在 sun.nio.ch.FileDispatcherImpl.read0( native 方法)上以 100% CPU 挂起

转载 作者:可可西里 更新时间:2023-11-01 17:10:29 25 4
gpt4 key购买 nike

(更新:与文件上传无关,更多细节在底部)

我在 jre-1.7.0-openjdk.x86_64 上运行 jetty-distribution-9.0.6.v20130930 服务器,运行在 EC2 linux 服务器。它是一个移动应用程序的后端,每天接收大约 5 万个请求。

大约一天一次,一个线程挂起 100% CPU,直到我杀死它(在 100% CPU 上运行几个小时后)。

JavaMelody 显示挂起线程的以下调用堆栈:

enter image description here

Jetty HTTP 连接器定义,来自 etc/jetty-https.xml:

<Call id="httpsConnector" name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ServerConnector">
<Arg name="server"><Ref refid="Server" /></Arg>
<Arg name="factories">
<Array type="org.eclipse.jetty.server.ConnectionFactory">
<Item>
<New class="org.eclipse.jetty.server.SslConnectionFactory">
<Arg name="next">http/1.1</Arg>
<Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg>
</New>
</Item>
<Item>
<New class="org.eclipse.jetty.server.HttpConnectionFactory">
<Arg name="config"><Ref refid="sslHttpConfig"/></Arg>
</New>
</Item>
</Array>
</Arg>
<Set name="host"><Property name="jetty.host" /></Set>
<Set name="port"><Property name="jetty.https.port" default="8443" /></Set>
<Set name="idleTimeout">30000</Set>
</New>
</Arg>
</Call>

Jetty HTTPS 配置,来自 start.ini:

jetty.https.port=8443
etc/jetty-https.xml

JVM 版本 -

java version "1.7.0_45"
OpenJDK Runtime Environment (amzn-2.4.3.2.32.amzn1-x86_64 u45-b15)
OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)

一个

问题

  1. 是什么原因造成的?

  2. 为什么没有触发超时来杀死这些挂起的线程?

  3. 如何启用此类场景的超时?

更新

原来这与文件上传无关,它有时也发生在不同的EC2服务器(相同配置),有时两个实例卡在完全相同的时间,具有相同的调用栈。

对方服务器没有实现文件上传,所以排除这个选项。

最佳答案

您配置了 30 秒超时,并且正在从移动设备上传 Mime/文件。

感觉线程卡住了。由于您使用的是移动客户端和 servlet 3.0,因此您应该考虑放弃使用 Apache Commons 文件上传,而只使用默认的 Servlet 3.0 HttpServletRequest.getParts()逻辑。这将允许 Jetty 本身使用各种可用的异步 I/O 技术来管理缓慢或有问题的客户端(这在移动客户端及其移动网络中极为常见)。

Apache Commons File Upload 使用较旧的技术,要求服务器切换到阻塞模式 I/O,这对于慢速客户端来说意味着阻塞 I/O 行为会导致持续时间很长的选择器旋转,并且永远不会有字节流实际上在空闲超时时绊倒了(从技术上讲,连接不是空闲的,仍然有流量,但速度非常慢)

您的选择:

  1. 既然你说这是一个移动应用程序(而不是移动浏览器),请从 POST 切换到文件上传(以及所有相关的 mime multipart/form-data 废话,你不需要)到 PUT 文件上传(这是一个更简单的请求内容类型)只是为了避免 Apache Commons File-Upload 层。当然,这需要更新应用程序。
  2. 升级和/或重新配置您的服务器端实现,以使用 Servlet 3.0(用于 Jetty 9.0.6)或 Servlet 3.1(用于 Jetty 9.1.0)标准技术来请求多部分内容,目标是消除 Apache Commons文件上传库。这将是仅服务器端更新。
  3. 在您的文件上传 servlet 前面添加一个过滤器,用于指定请求所需时间的总体上限,如果时间过长则终止连接。
  4. 彻底改变您从应用程序上传文件的方式,不使用 POST,降低性能限制,如果上传时间过长,失败,通知用户,让他们可以选择推迟上传直到他们在 wifi 上等(有些应用程序甚至有配置选项来上传内容,例如“在移动设备或 wifi 上”与“仅在 wifi 上”)

关于http - Jetty 在 sun.nio.ch.FileDispatcherImpl.read0( native 方法)上以 100% CPU 挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20379141/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com