Я использую Flask через Gunicorn, и у меня большая проблема. Я получаю [КРИТИЧЕСКИЕ] ошибки WORKER_TIMEOUT. Чтобы исправить это, я добавил «preload_app = True» в свою конфигурацию Gunicorn. Добавить почти работает. Проблема, с которой я столкнулся, заключается в том, что стрельба не запускается, если я не отправлю сигнал SIGINT. Это происходит только с preload_app.
Вот результат:
(.venv) ubuntu@server:/opt/mayapp$ gunicorn -c etc/gunicorn.conf.py myapp:app
^C[2020-06-18 18:02:46 +0000] [23412] [INFO] Starting gunicorn 19.10.0
[2020-06-18 18:02:46 +0000] [23412] [INFO] Listening at: http://0.0.0.0:8000 (23412)
[2020-06-18 18:02:46 +0000] [23412] [INFO] Using worker: eventlet
[2020-06-18 18:02:46 +0000] [23416] [INFO] Booting worker with pid: 23416
[2020-06-18 18:02:46 +0000] [23417] [INFO] Booting worker with pid: 23417
[2020-06-18 18:02:46 +0000] [23418] [INFO] Booting worker with pid: 23418
[2020-06-18 18:02:46 +0000] [23419] [INFO] Booting worker with pid: 23419
[2020-06-18 18:02:46 +0000] [23420] [INFO] Booting worker with pid: 23420
Обратите внимание на ^ C, прежде чем что-либо произойдет. Если я не прервусь, ожидание будет неопределенным. В дополнение к тому, чтобы не запускаться, когда я действительно хочу завершить работу, я должен "pkill -9". Он будет зависать часами с любым другим способом.
My gunicorn.conf.py:
# file gunicorn.conf.py
# coding=utf-8
# Reference: https://github.com/benoitc/gunicorn/blob/master/examples/example_config.py
import os
import multiprocessing
_ROOT = os.path.abspath(os.path.join(
os.path.dirname(__file__), '..'))
_VAR = os.path.join(_ROOT, 'var')
_ETC = os.path.join(_ROOT, 'etc')
loglevel = 'info'
# errorlog = os.path.join(_VAR, 'log/api-error.log')
# accesslog = os.path.join(_VAR, 'log/api-access.log')
errorlog = "-"
accesslog = "-"
# bind = 'unix:%s' % os.path.join(_VAR, 'run/gunicorn.sock')
bind = '0.0.0.0:8000'
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = 'eventlet'
preload_app = True
timeout = 3 * 60 # 3 minutes
keepalive = 24 * 60 * 60 # 1 day
capture_output = True
debug = True
Мое Flask Приложение:
import eventlet
eventlet.monkey_patch()
from flask import Flask, render_template, make_response
from flask_session import Session
from flask_cors import CORS
import os
app = Flask(__name__)
GEVENT_SUPPORT = True
cors = CORS(app)
app.secret_key = os.urandom(24)
app.config['SESSION_TYPE'] = 'filesystem'
app.config['SESSION_KEY_PREFIX'] = "myapp"
app.config['MAX_CONTENT_LENGTH'] = 5 * 1024 * 1024
app.config['GOOGLE_LOGIN_REDIRECT_SCHEME'] = "https"
if os.getenv('MYAPP', 'PROD') == 'DEV':
app.debug = True
app._static_folder = os.path.abspath("./app/templates/prod/static/")
if os.getenv('VTABLE', 'PROD') == 'DEV':
app._static_folder = os.path.abspath("./app/templates/dev/static/")
Session(app)
from app import routes
import app.sock as sock
if __name__ == 'app':
if os.getenv('VTABLE', 'PROD') == 'DEV':
sock.socketio.run(app, host='0.0.0.0', port=5000, keyfile='key.pem', certfile='cert.pem')
else:
sock.socketio.run(app, host='0.0.0.0', port=5000)
Начало app / sock.py:
from flask_session import Session
from flask_socketio import SocketIO
from flask_socketio import send, emit, join_room, leave_room
from cachelib.file import FileSystemCache
from engineio.payload import Payload
from engineio.async_drivers import eventlet
from werkzeug.middleware.proxy_fix import ProxyFix
import json
import random
import time
import uuid
from uuid import UUID
from app import app
from app import routes
Session(app)
socketio = SocketIO(app, async_mode='eventlet')
session = routes.session
@socketio.on('player_join')
def on_join(player_key):
join_room(player_key)