#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
#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