Тайм-аут с приложением Flask / uWSGI / nginx с использованием mongodb - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть веб-приложение на Python для Flask на uWSGI / nginx, которое прекрасно работает, за исключением случаев, когда я использую pymongo, особенно когда я инициализирую класс MongoClient.Я получаю следующую ошибку nginx при попытке получить доступ к приложению при использовании pymongo:

019/02/19 21:58:13 [error] 16699 # 0: * 5 recv () не удалось (104: Сброс соединения по одноранговой сети) при чтении заголовка ответа из апстрима, клиент: 127.0.0.1, сервер: example.com, запрос: «GET / api / test HTTP / 1.1», апстрим: «uwsgi: // unix: / var/www/html/myapp/myapp.sock: », хост:« example.com »

Мое небольшое тестовое приложение:

from flask import Flask
from flask_cors import CORS
from bson.json_util import dumps
import pymongo

DEBUG = True
app = Flask(__name__)
app.config.from_object(__name__)
CORS(app)

client = pymongo.MongoClient() # This line
db = client.myapp

@app.route('/api/test')
def test():
    item = db.items.find_one()
    return item['name']

def create_app(app_name='MYAPP'):
    return app

# if __name__ == '__main__':
#   app.run(debug=True, threaded=True, host='0.0.0.0')

Если я запускаю это приложение изкомандная строка (python app.py) работает нормально при доступе к 0.0.0.0:5000/api/test, так что я почти уверен, что это просто проблема конфигурации uWSGI. Моей первой мыслью было увеличение параметра uwsgi_read_timeout в моем конфигурационном файле nginx:

uwsgi_read_timeout 3600

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    server_name example.com www.example.com;

    location /api {
        include uwsgi_params;
        uwsgi_read_timeout 3600;
        uwsgi_pass unix:/var/www/html/myapp/myapp.sock;
    }

    location / {
      root /var/www/html/myapp;
      try_files $uri $uri/ /index.html;
    }

    #return 301 https://$server_name$request_uri;
}

Но это никак не повлияло. Мое приложение uWSGI работает как служба, используя следующую конфигурацию (myapp.ini):

[uwsgi]
module = wsgi:app

master = true
processes = 4
enable-threads = True

socket = /var/www/html/myapp/myapp.sock
chmod-socket = 660
vacuum = true

die-on-term = true

Опять же, все работает нормально, за исключением случаев, когда я пытаюсь инициализировать pymongo. Наконец, служебный файл моего приложения:

[Unit]
Description=uWSGI Python container server
After=network.target

[Service]
User=pi
Group=www-data
WorkingDirectory=/var/www/html/myapp
ExecStart=/usr/bin/uwsgi --ini /etc/uwsgi/apps-available/myapp.ini

[Install]
WantedBy=multi-user.target

1 Ответ

0 голосов
/ 20 февраля 2019

Я считаю, что проблема в том, что вы разветвляетесь, и это вызывает проблемы с PyMongo.

PyMongo является поточно-ориентированным, но не Fork-безопасным.После запуска приложения в режиме демона вы прекращаете процесс.Вам нужно создать MongoClient внутри приложения, чтобы ваши потоки могли видеть его после запуска процесса.

Вы можете попробовать это (я не пробовал, я обычно оборачиваю такие вещи вкласс и сделать это в init метод):

def create_app(app_name='MYAPP'):
   app.client = pymongo.MongoClient(connect=False) # this will prevent connecting until you need it.
   app.db = app.client.myapp
   return app

Читать это: http://api.mongodb.com/python/current/faq.html#id3

...