【问题标题】:NGINX + uWSGI Connection Reset by PeerNGINX + uWSGI 连接由 Peer 重置
【发布时间】:2012-10-15 08:00:23
【问题描述】:

我正在尝试使用 uWSGI 在 NGINX 上托管 Bottle 应用程序。

这是我的 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

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

我正在使用 POST 请求。为此,使用 dev 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"

怎么办?

【问题讨论】:

    标签: nginx uwsgi bottle


    【解决方案1】:

    确保在您的应用程序中使用您的帖子数据

    例如,如果你有一个 Django/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")
    

    一些细节:https://uwsgi-docs.readthedocs.io/en/latest/ThingsToKnow.html

    【讨论】:

    • 这彻底解决了我在 nginx-uwsgi-django 实现上的问题。我正在构建一个存根视图,最初并不关心入站 xml。小的入站 xml 可以工作,但较大的会得到对等方的重置。一旦我将body = request.body 添加到视图中,任何大小的帖子都开始起作用了。
    • 这也是我在 Django/UWSGI/Nginx 堆栈上遇到的问题。我不知道这是一件事。有这方面的任何文档/资源吗?为什么我必须使用 POST 数据?编辑:这里的一些细节(虽然很模糊):uwsgi-docs.readthedocs.org/en/latest/ThingsToKnow.html
    【解决方案2】:

    当请求的主体没有被消费时,就会出现这个问题,因为 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
    

    因此,要解决此问题,您需要确保始终阅读整个请求正文,或者在不需要时不发送正文(例如 DELETE)。

    【讨论】:

    • 这帮助很大!谢谢!
    【解决方案3】:

    不使用线程!

    我在 uwsgi 下的 Python 中的 Global Interpretator Lock 也有同样的问题。 当我不使用线程时 - 不重置连接。

    uwsgi 配置示例(服务器上的 1Gb Ram)

    [root@mail 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
    

    【讨论】:

      【解决方案4】:

      您无法从客户端发布数据,除非在您的应用程序中读取它。虽然这在 uWSGI 中不是问题,但 nginx 会失败。您可以使用 uWSGI 的 --post-buffering 选项“伪造”该东西以自动从套接字读取数据(如果可用),但您最好“修复”(即使我不认为这是一个错误)您的应用

      【讨论】:

      • 你会在你的应用中消费帖子数据吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      • 2017-07-19
      • 2020-04-29
      • 2019-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多