簡體   English   中英

使用mongodb的Flask / uWSGI / nginx應用超時

[英]Timeout with Flask/uWSGI/nginx app using mongodb

我在uWSGI / nginx上有一個Flask python網絡應用程序,除了我使用pymongo ,特別是在初始化MongoClient類時,都可以正常工作。 當我嘗試使用pymongo來訪問應用程序時出現以下nginx錯誤:

019/02/19 21:58:13 [錯誤] 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配置問題。 我的第一個想法是在我的nginx配置文件中增加uwsgi_read_timeout參數:

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

我相信問題是您在分叉,這會導致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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM