首页 > 解决方案 > Nginx - 从上游读取响应标头时上游过早关闭连接

问题描述

我有一个关于 nginx 的问题,它可能比看起来更复杂。我有一个用烧瓶编写的应用程序,它在本地工作得很好。我在 Ubuntu 16.04.6 LTS 上设置它。我安装了 Nginx 1.10.3 并将其配置为代理。数据库是 MongoDB v4.2.3 我在本教程中设置了 Gunicorn:https ://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on- ubuntu-18-04

问题是,当我尝试从 mongo 加载数据时,它会尝试处理请求 30 秒,然后抛出502 Bad Gateway。我查看了nginx 的 error.log

[error] 12361#12361: *28 upstream prematurely closed connection while reading response header from upstream, client: 123.123.123.123, server: example.com, request: "GET /example_route/view_database/ HTTP/1.1", upstream: "http://unix:/home/user/flaskapp/src/application.sock:/example_route/view_database/", host: "example.com", referrer: "http://example.com/example_route"

至于mongod.log

2020-04-09T22:18:29.534+0200 W  QUERY    [conn89] Plan executor error during distinct command: FAILURE, status: ClientDisconnect: operation was interrupted because a client disconnected, stats: { stage: "COLLSCAN", nReturned: 2745, executionTimeMillisEstimate: 24703, works: 2746, advanced: 2745, needTime: 1, needYield: 0, saveState: 1378, restoreState: 1377, isEOF: 0, direction: "forward", docsExamined: 2745 }
2020-04-09T22:18:29.534+0200 W  COMMAND  [conn89] Unable to gather storage statistics for a slow operation due to lock aquire timeout
2020-04-09T22:18:29.534+0200 I  COMMAND  [conn89] command db_name.col_name command: distinct { distinct: "elem", key: "some_key", lsid: { id: UUID("someid") }, $db: "db_name", $readPreference: { mode: "primaryPreferred" } } planSummary: COLLSCAN numYields:1378 ok:0 errMsg:"Executor error during distinct command :: caused by :: operation was interrupted because a client disconnected" errName:ClientDisconnect errCode:279 reslen:202 locks:{ ReplicationStateTransition: { acquireCount: { w: 1379 } }, Global: { acquireCount: { r: 1379 } }, Database: { acquireCount: { r: 1378 } }, Collection: { acquireCount: { r: 1378 } }, Mutex: { acquireCount: { r: 1 } } } protocol:op_msg 30475ms
2020-04-09T22:18:29.535+0200 I  NETWORK  [conn89] end connection 127.0.0.1:40296 (5 connections now open)
2020-04-09T22:18:29.614+0200 I  NETWORK  [conn88] end connection 127.0.0.1:40294 (4 connections now open)
2020-04-09T22:18:30.136+0200 I  NETWORK  [listener] connection accepted from 127.0.0.1:40310 #96 (5 connections now open)
2020-04-09T22:18:30.137+0200 I  NETWORK  [conn96] received client metadata from 127.0.0.1:40310 conn96: { driver: { name: "PyMongo", version: "3.10.1" }, os: { type: "Linux", name: "Linux", architecture: "x86_64", version: "4.4.0-165-generic" }, platform: "CPython 3.5.2.final.0" }
2020-04-09T22:18:30.160+0200 I  NETWORK  [listener] connection accepted from 127.0.0.1:40312 #97 (6 connections now open)
2020-04-09T22:18:30.160+0200 I  NETWORK  [conn97] received client metadata from 127.0.0.1:40312 conn97: { driver: { name: "PyMongo", version: "3.10.1" }, os: { type: "Linux", name: "Linux", architecture: "x86_64", version: "4.4.0-165-generic" }, platform: "CPython 3.5.2.final.0" }

另一件事是,当我尝试将数据上传到服务器时(上传对我来说更重要),我得到的只是一个弹出窗口,如下所示:

example.com says

INTERNAL SERVER ERROR

nginx 的 error.log中没有关于它的数据。当我在浏览器中查看开发控制台时,我只看到:

POST http://example.com/example_route/send 500 (INTERNAL SERVER ERROR)

这两件事都在我的笔记本电脑上本地运行得很好。

nginx服务器配置:

server {
        listen 80;
        listen [::]:80;
        server_name example.com www.example.com;
        client_max_body_size 100M;
        location /static {
                alias /home/user/flaskapp/src/app_here/static;
        }

        location / {
                include proxy_params;
                proxy_pass http://unix:/home/user/flaskapp/src/application.sock;
                proxy_redirect off;
                proxy_max_temp_file_size 16400M;
                proxy_buffering off;
                proxy_http_version 1.1;
                proxy_read_timeout 36000s;
        }
}

Gunicorn 进程配置:

[Unit]
Description=Gunicorn instance to serve flaskapp
After=network.target

[Service]
User=user
Group=www-data
WorkingDirectory=/home/user/flaskapp
Environment="PATH=/home/user/flaskapp/venv/bin"
ExecStart=/home/user/flaskapp/venv/bin/gunicorn --workers 3 --bind unix:application.sock -m 007 wsgi:app

[Install]
WantedBy=multi-user.target

在python中向服务器发送数据的函数:

@main.route('/example_route/send', methods=['POST'])
@login_required
def send():
    data = request.json
    new_data = Data_model(
        timestamp = data['Timestamp'],
        area = data["Area"],
        image = data["Image"]
    ).save()
    return redirect(url_for('main.data_viewer'))

和客户端的js:

$.ajax({
        url: '/example_route/send',
        type: "POST",
        data: JSON.stringify(sendDict),
        contentType: "application/json",
        success: function (data) {
// success code
        },
        error: function (request, status, error) {
            alert(request.statusText);
        },
    });

至于从服务器读取数据是:

@db_viewer.route('/example_route/view_database/')
@login_required
def view_database():
    data = Data.objects.only('UID').distinct('UID')
    return render_template('example_app/view_database.html', ids=data, user=current_user)

总而言之,有两个问题会带来噩梦,而我就是无法解决它们:

只是服务器上的问题,在本地都可以正常工作。

标签: pythonlinuxmongodbnginxserver

解决方案


推荐阅读