Hessian HTTP POST访问时,Nginx返回411问题

#1 问题描述# 用 Hessian 实现 web service 过程当中,须要建立对象时,是使用 HTTP POST 方法来传递数据的。可是在有反向代理 (nginx)的状况下,会抛出异常 (com.caucho.hessian.client.HessianConnectionException: 411:java.io.IOException: Server returned HTTP response code: 411 for URL:http://xxxx/xxx/xxxService) 。java

首先来看下 HTTP 411 错误的解释: Length Required 服务器不能处理请求,除非客户发送一个 Content-Length 头。( HTTP 1.1 新)这是由于Hessian 与服务端通讯默认是采起分块的方式 (chunked encoding) 发送数据,而反向代理要得到 Content-Length 这个头,才能处理请求,可是 Hessian 的请求中并无加入这个参数nginx

#2 排查过程#git

  1. 不经过Nginx反向代理时,Hessian接口访问正常;【正常】
  2. 查看Nginx的日志access.log,是有Nginx返回411状态;【不正常】

#3 解决问题# com.caucho.hessian.client.HessianProxyFactory 类中,有一个 boolean _chunckedPost 的域成员,其默认值为 true 。这个值就是规定 Hessian 是否以分块发送的方式与服务端交换数据的参数,所以在建立 com.caucho.hessian.client.HessianProxyFactory 的对象后(假设为 factory ),只要调用其上的 setChunckedPost() 方法,把这个属性设置为 false 便可。即 factory.setChunkedPost(false);github

#4 问题总结# 分块编码 (chunked encoding) 传输方式是 HTTP 1.1 协议中定义的 Web 用户向服务器提交数据的一种方法,当服务器收到 chunked 编码方式的数据时会分配一个缓冲区存放之,若是提交的数据大小未知,客户端会以一个协商好的分块大小向服务器提交数据。web

若是不使用 Chunked encoding 传输方式,须要将要发送的数据缓存下来,计算出 content-length ,从而知足反向代理( Nginx )须要 content-length 的要求缓存

该问题还能够经过修改 nginx 配置,使得 nginx 能够处理分块编码 (chunked encoding) 传输方式。在使用Nginx 1.3.9如下版本,都存在当用户POST一个带有文件的请求的时候,出现HTTP 411错误。 这个是Nginx的问题,须要打一个补丁。服务器

#下载chunkin模块
git clone https://github.com/agentzh/chunkin-nginx-module.git
#编译nginx,使用chunkin模块
wget http://nginx.org/download/nginx-1.2.7.tar.gz
tar xvzf nginx-1.2.7.tar.gz
cd nginx-1.2.7
./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-http_gzip_static_module --with-google_perftools_module --with-http_realip_module --add-module=../chunkin-nginx-module 
make -j8
make install

添加 HttpChunkinModule 解决。因为这个模块已经内置到了 nginx 1.3.9 之后的 nginx 核心了,因此原来的 nginx 1.4.x 没有这个问题。模块介绍和具体安装过程见:http://wiki.nginx.org/HttpChunkinModule,把这个模块编译进去后给 server 节点添加一个配置就能够了:ui

server {
    chunkin on;
    error_page 411 = @my_411_error;
    location @my_411_error {
        chunkin_resume;
    }
}

以后重启nginx就能够了。google

相关文章
相关标签/搜索