2012-10-25 102 views
7

我正嘗試使用uWSGI在NGINX上託管瓶應用程序。NGINX + uWSGI連接重置通過對端

這裏是我的nginx.conf

location /myapp/ { 
     include uwsgi_params; 
     uwsgi_param X-Real-IP $remote_addr; 
     uwsgi_param Host $http_host; 
     uwsgi_param UWSGI_SCRIPT myapp; 
     uwsgi_pass 127.0.0.1:8080; 
    } 

我,因爲這

uwsgi --enable-threads --socket :8080 --plugin python -- wsgi-file ./myApp/myapp.py 

運行uwsgi我使用POST請求。對於那個使用開發Http客戶端。當我發送

http://localhost/myapp 

uWSGI服務器接收請求,並打印

[pid: 4683|app: 0|req: 1/1] 127.0.0.1() {50 vars in 806 bytes} [Thu Oct 25 12:29:36 2012] POST /myapp => generated 737 bytes in 11 msecs (HTTP/1.1 404) 2 headers in 87 bytes (1 switches on core 0) 

但在Nginx的錯誤日誌

2012/10/25 12:20:16 [error] 4364#0: *11 readv() failed (104: Connection reset by peer) while reading upstream, client: 127.0.0.1, server: localhost, request: "POST /myApp/myapp/ HTTP/1.1", upstream: "uwsgi://127.0.0.1:8080", host: "localhost" 

怎麼辦請求肚裏無限?

回答

6

如果未在應用程序中讀取數據,則無法發佈數據。雖然這在uWSGI中不是問題,但nginx會失敗。您可以使用uWSGI的--post-buffering選項來自動從套接字讀取數據(如果有的話),但您最好「修復」(即使我不認爲這是一個錯誤)應用程序

+0

我已經嘗試過 - post-buffering 32768.仍然沒有工作 –

+2

您是否在應用程序中使用了發佈數據? – RickyA

1

不使用線程!

我在uwsgi下的Python中的Global Interpretator Lock存在同樣的問題。 當我不使用線程 - 沒有連接重置。 uwsgi配置的

例(1GB內存在服務器上)

[[email protected] uwsgi]# cat myproj_config.yaml 
uwsgi: 
    print: Myproject Configuration Started 
    socket: /var/tmp/myproject_uwsgi.sock 
    pythonpath: /sites/myproject/myproj 
    env: DJANGO_SETTINGS_MODULE=settings 
    module: wsgi 
    chdir: /sites/myproject/myproj 
    daemonize: /sites/myproject/log/uwsgi.log 
    max-requests: 4000 
    buffer-size: 32768 
    harakiri: 30 
    harakiri-verbose: true 
    reload-mercy: 8 
    vacuum: true 
    master: 1 
    post-buffering: 8192 
    processes: 4 
    no-orphans: 1 
    touch-reload: /sites/myproject/log/uwsgi 
    post-buffering: 8192 
5

一定要消耗你的投稿數據在應用程序

例如,如果你有一個Python應用程序

def my_view(request): 

    # ensure to read the post data, even if you don't need it 
    # without this you get a: failed (104: Connection reset by peer) 
    data = request.DATA 

    return HttpResponse("Hello World") 
+1

這確實解決了我在nginx-uwsgi-django實現中遇到的問題。我正在構建存根視圖,並且最初並不關心入站xml。小的入站xml可以工作,但是較大的入站xml會被同級重置。一旦我將'body = request.body'添加到視圖中,任何大小的帖子都開始工作。 – bskinnersf

+2

這對我來說也是Django/UWSGI/Nginx堆棧中的問題。我不知道這是一件事。有沒有關於此的任何文檔/資源?爲什麼我必須使用POST數據?編輯:一些細節(儘管很模糊)在這裏:http://uwsgi-docs.readthedocs.org/en/latest/ThingsToKnow.html –

3

當請求的正文沒有被使用時會發生此問題,因爲uwsgi無法知道它在某個時刻是否仍然需要。所以uwsgi會一直持有數據,直到它被使用或直到nginx重置連接(因爲上行超時)。

uwsgi的作者解釋它here

08:21 < unbit> plaes: does your DELETE request (not-response) have a body ? 
08:40 < unbit> and do you read that body in your app ? 
08:41 < unbit> from the nginx logs it looks like it has a body and you are not reading it in the app 
08:43 < plaes> so DELETE request shouldn't have the body? 
08:43 < unbit> no i mean if a request has a body you have to read/consume it 
08:44 < unbit> otherwise the socket will be clobbered 

因此,要解決這個問題,你需要確保始終無論是讀取整個請求體或不發送體,如果它是沒有必要的(對於刪除例如)。

+0

這有助於很多!謝謝! – vincent