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

相關文章
相關標籤/搜索