这有点奇怪,因为我已经用同样的方法部署我的Flask应用超过2年了,但根据技术栈的不同有一些小的差异。当我运行Flask应用时,没有为gunicorn指定host:port,如下所示。
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 [email protected]
2020-05-30T10:32:09.146144+00:00 app[api]: Release v39 created by user [email protected]
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
这是我的应用程序启动.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
我希望我真的能找到答案,因为这对我来说没有什么意义 尤其是在没有日志或错误的情况下。我希望有一个工作,使端口固定,以使我的套接字工作。非常感谢你的时间和帮助。
好吧,所以我添加了什么,使这项工作基本上是使用。
web: gunicorn --worker-class eventlet -w 1 wsgi:app
或者...
web: gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 wsgi:app
在procfile中互换,但在我的应用程序中做了一个小的修改。启动.py,在初始化socketio的时候。
socket.init_app(app, cors_allowed_origins="*",
async_mode='gevent',
engineio_logger=True,
logger=True,
port=8000)
我基本上为套接字添加了一个8000的端口来代理请求,而不是Gunicorn端口,在服务器启动之前,前端是未知的,如果是这样的话。我仍然不知道为什么当我指定主机和名称时服务器会崩溃,我希望我找到一个答案,但我很高兴我的应用程序和套接字现在可以正常工作。