Gunicorn Flask Restful API и Flask -Socketio вылетает, когда я привязываю хост и порт к Gunicorn - PullRequest
0 голосов
/ 30 мая 2020

Это немного странно, так как я развертываю свои Flask приложения уже более 2 лет, используя один и тот же способ с небольшими различиями в зависимости от технического стека. Когда я запускаю свое приложение Flask без указания порта host: для gunicorn следующим образом:

web: gunicorn --worker-class eventlet -w 1 wsgi:app

как указано в документах здесь , оно работает нормально, но мои сокеты не Нет, поскольку сервер Gunicorn каждый раз запускается практически с другого порта, что не позволяет указать фиксированный порт во внешнем интерфейсе. Вот почему я указываю хост и порт следующим образом:

web: gunicorn --bind 127.0.0.1:8000 --worker-class eventlet -w 1 wsgi:app

Я должен отметить, что я также пробовал другие альтернативы, например:

web: gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker --bind 127.0.0.1:8000 -w 1 wsgi:app

Что происходит здесь, это приложение успешно развертывается также, когда я привязываю хост и адрес, но вылетает без журналов или ошибок, когда это действительно расстраивает. Что больше расстраивает, так это то, что он работает без проблем на локальном хосте, если я не указываю адрес. Вот мои журналы Heroku:

2020-05-30T10:32:09.146144+00:00 app[api]: Deploy 37f7668f by user use@email.com
2020-05-30T10:32:09.146144+00:00 app[api]: Release v39 created by user user@emai.com
2020-05-30T10:32:20.484467+00:00 app[web.1]: [2020-05-30 10:32:20 +0000] [4] [INFO] Starting gunicorn 20.0.4
2020-05-30T10:32:20.485325+00:00 app[web.1]: [2020-05-30 10:32:20 +0000] [4] [INFO] Listening at: http://127.0.0.1:8000 (4)
2020-05-30T10:32:20.485476+00:00 app[web.1]: [2020-05-30 10:32:20 +0000] [4] [INFO] Using worker: eventlet
2020-05-30T10:32:20.490925+00:00 app[web.1]: [2020-05-30 10:32:20 +0000] [9] [INFO] Booting worker with pid: 9
2020-05-30T10:32:22.886718+00:00 app[web.1]: Server initialized for eventlet.
2020-05-30T10:32:26.000000+00:00 app[api]: Build succeeded
2020-05-30T10:33:17.674322+00:00 heroku[web.1]: State changed from starting to crashed
2020-05-30T10:33:18.184411+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=langcodex.herokuapp.com request_id=d0742a73-96a0-490e-860b-e0ccda544e0b fwd="41.92.113.84" dyno= connect= service= status=503 bytes= protocol=https
2020-05-30T10:33:19.352104+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=langcodex.herokuapp.com request_id=8f202689-ee4c-4871-bfe3-ef8f9c34b397 fwd="41.92.113.84" dyno= connect= service= status=503 bytes= protocol=https

Вот мое приложение / init .py файл:

import logging, os
from logging.handlers import SMTPHandler, RotatingFileHandler
from flask import Flask
from flask_socketio import SocketIO
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_mail import Mail
from flask_migrate import Migrate
from flask_seasurf import SeaSurf
from flask_cors import CORS
from config import Config, Development


db = SQLAlchemy()
login_manager = LoginManager()
migrate = Migrate()
mail = Mail()
seasurf = SeaSurf()
socket = SocketIO()
cors = CORS()


def create_app(config_class=Config):
    """Construct the core application."""
    app = Flask(__name__, static_folder='frontend/build/static', 
        instance_relative_config=True)
    # Application Configuration
    app.config.from_object(config_class)
    with app.app_context():
        # Initialize Plugins
        login_manager.init_app(app)
        db.init_app(app)
        mail.init_app(app)
        migrate.init_app(app, db)
        seasurf.init_app(app)
        cors.init_app(app, resources={r'/api/*': {'origins': '*'}})
        socket.init_app(app, cors_allowed_origins="*", 
            async_mode='eventlet', 
            engineio_logger=True, 
            logger=True)
        # Initialize Global db
        db.create_all()
        from app.serve_frontend_bp import serve_frontend_bp as serve_frontend_blueprint
        app.register_blueprint(serve_frontend_blueprint)
        from app.socket_bp import socket_bp as socket_blueprint
        app.register_blueprint(socket_blueprint)
        from app.nlp_bp import nlp_bp as nlp_blueprint
        app.register_blueprint(nlp_blueprint, url_prefix='/api/nlp')
        from app.main_bp import main_bp as main_blueprint
        app.register_blueprint(main_blueprint, url_prefix='/api')
        from app.errors_bp import errors_bp as errors_blueprint
        app.register_blueprint(errors_blueprint)
        # Configute Debugging
        if app.debug or app.testing:

            if app.config['LOG_TO_STDOUT']:
                stream_handler = logging.StreamHandler()
                stream_handler.setLevel(logging.INFO)
                app.logger.addHandler(stream_handler)
            else:
                if not os.path.exists('logs'):
                    os.mkdir('logs')
                file_handler = RotatingFileHandler('logs/langandcode.log',
                                                   maxBytes=20480, backupCount=20)
                file_handler.setFormatter(logging.Formatter(
                    '%(asctime)s %(levelname)s: %(message)s '
                    '[in %(pathname)s:%(lineno)d]'))
                file_handler.setLevel(logging.INFO)
                app.logger.addHandler(file_handler)
            app.logger.setLevel(logging.INFO)
            app.logger.info('LanguageandCode startup')
        return app

Вот моя структура приложения:

.
├── app
│   ├── auth_bp
│   ├── core
│   ├── decorators.py
│   ├── email.py
│   ├── errors_bp
│   ├── exceptions.py
│   ├── factory.py
│   ├── forms.py
│   ├── frontend
│   ├── functions.py
│   ├── __init__.py
│   ├── logs
│   ├── main
│   ├── main_bp
│   ├── models.py
│   ├── nlp_bp
│   ├── __pycache__
│   ├── serve_frontend_bp
│   ├── socket_bp
│   └── templates
├── config.py
├── latest.dump
├── logs
│   └── langandcode.log
├── migrations
│   ├── alembic.ini
│   ├── env.py
│   ├── __pycache__
│   ├── README
│   ├── script.py.mako
│   └── versions
├── Procfile
├── requirements.txt
├── runtime.txt
└── wsgi.py

Надеюсь, я действительно найду ответ на этот вопрос, поскольку для меня это не имеет особого смысла, особенно без журналов или ошибок. Я надеюсь, что есть работа, чтобы исправить порт, чтобы мои сокеты работали. Большое спасибо за ваше время и помощь.

1 Ответ

0 голосов
/ 30 мая 2020

Хорошо, так что то, что я добавил, чтобы заставить эту работу, по сути, использует:

web: gunicorn --worker-class eventlet -w 1 wsgi:app

или

web: gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 wsgi:app

взаимозаменяемо в файле proc с одной незначительной модификацией в моем приложении / init .py, при инициализации socketio:

        socket.init_app(app, cors_allowed_origins="*", 
        async_mode='gevent', 
        engineio_logger=True, 
        logger=True, 
        port=8000) 

я в основном добавил порт 8000 для сокетов для прокси-запросов вместо порта Gunicorn, который неизвестен веб-интерфейсу до сервер запускается, если это так. Я до сих пор не знаю, почему сервер выходит из строя, когда я указываю хост и имя, и надеюсь, что найду ответ, но я рад, что мое приложение и сокеты теперь работают правильно.

...