我在Heroku上托管了一个应用程序,该应用程序使用运行遗传算法的烧瓶/芹菜api,当celery后台任务仍在运行并产生成功结果时,myoku应用程序会产生应用程序错误(关键工作者超时)。我不确定自己在做什么错。
以下是heroku日志(链接由于其较长):https://hastebin.com/ifakexilep.vbs
这是我的app.py代码:
from flask import Flask, request, jsonify
from flask_restful import Resource, Api
from celery import Celery
from json import dumps
import json
import os
import pandas as pd
from redis import Redis
import full_ga
app = Flask(__name__)
app.config['CELERY_BROKER_URL'] = os.environ.get('REDISCLOUD_URL')
app.config['CELERY_RESULT_BACKEND'] = os.environ.get('REDISCLOUD_URL')
#celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
#celery.conf.update(app.config)
def make_celery(app):
celery = Celery(
app.import_name,
backend=app.config['CELERY_RESULT_BACKEND'],
broker=app.config['CELERY_BROKER_URL']
)
celery.conf.update(app.config)
class ContextTask(celery.Task):
def __call__(self, *args, **kwargs):
with app.app_context():
return self.run(*args, **kwargs)
celery.Task = ContextTask
return celery
celery = make_celery(app)
api = Api(app)
def jsonify(data):
json_data = dict()
for key, value in data.items():
if isinstance(value, list): # for lists
value = [ jsonify(item) if isinstance(item, dict) else item for
item in value ]
if isinstance(value, dict): # for nested lists
value = jsonify(value)
if isinstance(key, int): # if key is integer: > to string
key = str(key)
if type(value).__module__=='numpy': # if value is numpy.*: > to
python list
value = value.tolist()
json_data[key] = value
return json_data
@celery.task(name='__main__.generate_plan')
def generate_plan(experience_level, plan_length_in_months,
num_workouts_per_week):
w = full_ga.full_ga(experience_level, plan_length_in_months,
num_workouts_per_week)
p = w.plan_ga()
#sleep(1000)
return jsonify(p)
class create_workout_plan(Resource):
def get(self, experience_level, plan_length_in_months,
num_workouts_per_week):
plan = generate_plan.delay(experience_level, plan_length_in_months,
num_workouts_per_week)
return plan.get()
api.add_resource(create_workout_plan,
'/<experience_level>/<plan_length_in_months>/<num_workouts_per_week>')
if __name__ == '__main__':
app.run()
对于可能出问题的任何帮助/提示,将不胜感激!
答案 0 :(得分:0)
app.run()
调用默认情况下绑定到127.0.0.1(localhost),端口5000。Heroku希望您的应用绑定到1)通过2)它传递给应用程序的端口的外部可见地址(通过PORT
环境变量)。如果您的应用未在30秒内绑定,则Heroku会将其标记为崩溃。
将其更改为:
app.run(host='0.0.0.0', port=os.environ.get('PORT', '5000'))
您当然需要在脚本的序言中添加import os
。
希望有帮助。