http - Tomcat 偶尔会返回没有 HTTP 标头的响应
问题描述
我正在调查 Tomcat ( 7.0.90 7.0.92) 偶尔返回没有 HTTP 标头的响应的问题。
根据Wireshark抓包,Tomcat收到请求后,只返回一个响应体。它既不返回状态行也不返回 HTTP 响应标头。
它使下游的 Nginx 实例产生错误“upstream sent no valid HTTP/1.0 header while reading response header from upstream”,向客户端返回 502 错误并关闭 Nginx 和 Tomcat 之间相应的 http 连接。
这种行为的原因可能是什么?是否有任何可能使 Tomcat 以这种方式运行?或者在某些情况下可能有一些东西会去除 HTTP 标头?或者 Wireshark 未能捕获包含 HTTP 标头的帧?任何缩小问题范围的建议也非常感谢。
这是 Wireshark 的“Follow HTTP Stream”的屏幕截图,显示了有问题的响应:
编辑:
这是相关部分的“TCP Stream”的屏幕截图(仅响应)。似乎最后一个响应中的第二个块看起来不错:
编辑2:
我将此问题转发到 Tomcat 用户邮件列表,并从开发人员那里得到了一些进一步调查的建议:
但我还没有找到任何合适的解决方案。我仍在寻找解决此问题的见解..
解决方案
您遇到的问题源于通过与上游的单个连接对多个请求进行管道传输,正如Eugène Adell昨天的回答所解释的那样。
无论这是 nginx、tomcat、您的应用程序中的错误,还是上述任何组合的交互,都可能是另一个论坛的讨论,但现在,让我们考虑什么是最好的解决方案:
你可以发布你的nginx配置吗?具体来说,如果您正在使用nginx
keepalive
中的非默认值?proxy_http_version
– cnst 1 小时前@cnst 我正在使用
proxy_http_version 1.1
和keepalive 100
– Kohei Nozaki 1 小时前
根据SO 上一个不相关问题的较早答案,但如上所述共享配置参数,您可能需要重新考虑在前端负载均衡器(例如,nginx)和后端应用服务器(例如,tomcat)。
根据nginx 上下文中关于 ServerFault 的 keepalive 解释,upstream
直到最近在 nginx 开发年代,才支持 nginx 上下文中的 keepalive 功能。为什么?这是因为当建立新连接比等待现有连接可用时基本上更快时,使用 keepalive 的有效场景很少:
当客户端和服务器之间的延迟大约为 50 毫秒+时,keepalive 可以重用 TCP 和 SSL 凭据,从而显着提高速度,因为不需要额外的往返来使连接准备好为 HTTP 提供服务要求。
这就是为什么你永远不应该禁用客户端和 nginx 之间的 keepalive(通过http://nginx.org/r/keepalive_timeout 和上下文控制)。
http
server
location
但是当前端代理服务器和后端应用服务器之间的延迟在 1 毫秒(0.001 秒)的数量级时,使用
keepalive
是一种追逐黑森虫的秘诀,而不会获得任何好处,因为建立连接的额外 1 毫秒延迟可能是小于等待现有连接可用的 100 毫秒延迟。keepalive
(这是对连接处理的过度简化,但它只是向您展示了前端负载均衡器和应用程序服务器之间的任何可能的好处是多么微不足道,前提是它们都位于同一区域。)这就是为什么在上下文中使用http://nginx.org/r/keepalive
upstream
很少是一个好主意,除非你真的需要它,并且已经特别验证了它会产生你想要的结果,鉴于上述几点。(而且,为了清楚起见,这些要点与您使用的实际软件无关,因此,即使您没有遇到使用 nginx 和 tomcat 组合时遇到的问题,我仍然建议您不要即使您决定从 nginx 和 tomcat 中的一个或两个切换,也要在负载均衡器和应用程序服务器之间使用 keepalive。)
我的建议?
使用http://nginx.org/r/proxy_http_version和http://nginx.org/r/keepalive的默认值将无法重现该问题。
如果您的后端在前端的 5 毫秒内,那么您肯定不会从一开始修改这些指令中获得任何好处,因此,除非追逐 Heisenbugs 是您的道路,否则您最好保留这些特定设置合理的默认值。
推荐阅读
- c - 几乎完整的C初学者。请解释我该如何解决这个问题
- powershell - AWS CLI 命令未从 Varaible 中选择 ASG 名称
- javascript - 如何悬停更改汉堡菜单颜色,单击汉堡菜单将其转换为 x 并具有内容下拉菜单?
- python-3.x - 在 Pytesseract 中将列中提取的文本设置为单个字符串
- flutter - 在 Flutter 中的 Google 地图中的多边形中创建一个洞
- ssis - SSISDB - 删除执行记录?
- pdf - 如何拼写检查pdf文档?
- python - 用于以高数据包速率进行实时数据包捕获的 Python 解决方案
- kubernetes - 等待 HTTP-01 质询传播:未能执行自检 GET 请求 - ISTIO
- docker - 无法连接到本地主机上的 docker 容器