Nginx走HttpProxy连JBoss在上传文件时的一个bug,及其解决

简介:
问题描述:

Nginx作为前端HttpServer  使用HttpProxy与JBoss进行连接
在上传比较大的文件时,JBoss已经返回结果,但是Nginx不立即将结果返回给浏览器,直到Nginx的HttpProxy与JBoss因为超时而断开后才返回结果给浏览器  这样导致的结果就是用户觉得上传文件需要很长时间.
问题原因分析:

Nginx HttpProxy转发的请求是Http 1.0的,就是说是不支持Keep-Alive的,那么也就是说只有当JBoss主动断开与HttpProxy的连接,或是超时被动断开,Nginx才认为这个请求已经完结了. 在看一下业务代码,因为在上传处理逻辑中会先进行一些前置判断,一旦判断失败,会不读取上传的文件然后直接返回一个Failed的Response回去,而这个时候就会出现上述的问题.
用Wireshark抓包分析HttpProxy与JBoss之间的通信发现,当JBoss一返回Response之后Nginx就会立马停止向JBoss Post数据,但是JBoss这个时候却不会断开与Nginx的连接. 再分析一下JBoss(即Tomcat)的对于endRequest的源码:

在当Tomcat处理完servlet后在org.apache.coyote.http11.Http11AprProcessor#endRequest的过程当中org.apache.coyote.http11.filters.IdentityInputFilter#end 会去读完所有的Content-Length这个长度的请求后才会Close连接,但是这个时候Nginx已经停止Post了,那么org.apache.coyote.http11.filters.IdentityInputFilter#end 取不到要取的数据就只有等待soTimeout(即配置的connectionTimeout)之后才超时断开连接,这个时候Nginx才会返回response给真正的Client 原因就是因为Nginx的处理和JBoss的处理不兼容引起的
问题解决:

* 需要在Servlet里面读完整个Request,或用一个Filter来读完也可以
本文来源于"阿里中间件团队播客",原文发表时间"  2011-09-10"
相关文章
|
应用服务中间件 测试技术 API
nginx文件夹内文件解释<一>
nginx文件夹内文件解释<一>
304 1
|
Kubernetes 应用服务中间件 nginx
k8s学习--YAML资源清单文件托管服务nginx
k8s学习--YAML资源清单文件托管服务nginx
539 2
k8s学习--YAML资源清单文件托管服务nginx
|
JavaScript 应用服务中间件 PHP
nginx server 禁止特定目录下的某类文件访问
【8月更文挑战第26天】这段Nginx配置代码旨在保护`/uploads/`目录下的文件,禁止执行任何`.php`, `.html`, `.htm`, 或 `.js`等潜在有害文件,即便被访问也无法运行。取而代之的是重定向到首页。为了实现这一设置,用户需要定位到对应子域名的`.conf`配置文件中进行相应修改。若网站支持多个访问域名,则需确保在正确的`.conf`文件中实施此配置。
598 1
|
存储 监控 应用服务中间件
查看nginx日志文件
器性能和提高网站可用性。掌握日志文件的路径、查看方法和基本分析技能对于任何服务器管理员来说都是必备技能。
1976 1
|
JavaScript 前端开发 应用服务中间件
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
1002 0
|
存储 网络协议 应用服务中间件
nginx文件夹内文件解释<六>
nginx文件夹内文件解释<六>
207 3
|
JSON 前端开发 应用服务中间件
nginx文件夹内文件解释<五>
nginx文件夹内文件解释<五>
228 3
|
应用服务中间件 nginx
nginx文件夹内文件解释<四>
nginx文件夹内文件解释<四>
223 3
|
应用服务中间件 nginx Ruby
nginx文件夹内文件解释<七>
nginx文件夹内文件解释<七>
226 2
|
应用服务中间件 nginx
nginx文件夹内文件解释<三>
nginx文件夹内文件解释<三>
272 1