Heroku应用程序产生应用程序错误(“关键工作人员超时”),而celery后台任务产生成功结果,我在做什么错呢?

时间:2018-07-10 04:12:00

标签: python heroku flask redis celery

我在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()

对于可能出问题的任何帮助/提示,​​将不胜感激!

1 个答案:

答案 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

希望有帮助。