Python芹菜pymysql任务连接过早关闭

时间:2018-11-27 09:40:47

标签: python mysql heroku sqlalchemy celery

我正在使用celery / redis和python / flask处理一些非常长的后台任务。我正在使用heroku托管该项目。

在任务中,我正在连接到mysql数据库。我在这里使用pymysql和sqlalchemy。

重要说明:该问题仅发生在heroku上,始终在localhost上起作用。

任务被一一执行。我的芹菜有很多问题,但这不是这里的问题(如果有人感兴趣,这里是old question)。

经过所有这些时间和测试,我认为问题可能出在MySQL过早关闭连接。

这是一个任务:

@shared_task(bind=True, name="get_gross_revenue_task")
def get_gross_revenue_task(self, g_start_date, g_end_date, START_TIME_FORM):

    db_session.close()
    start_date = datetime.strptime(g_start_date, '%d-%m-%Y')
    end_date = datetime.strptime(g_end_date, '%d-%m-%Y')

    gross_rev_trans_VK = db_session.query(func.sum(UsersTransactionsVK.amount)).filter(UsersTransactionsVK.date_added >= start_date, UsersTransactionsVK.date_added <= end_date, UsersTransactionsVK.payed == 'Yes').scalar()
    gross_rev_trans_Stripe = db_session.query(func.sum(UsersTransactionsStripe.amount)).filter(UsersTransactionsStripe.date_added >= start_date, UsersTransactionsStripe.date_added <= end_date, UsersTransactionsStripe.payed == 'Yes').scalar()
    gross_rev_trans = db_session.query(func.sum(UsersTransactions.amount)).filter(UsersTransactions.date_added >= start_date, UsersTransactions.date_added <= end_date, UsersTransactions.on_hold == 'No').scalar()

    if gross_rev_trans_VK is None:
        gross_rev_trans_VK = 0

    if gross_rev_trans_Stripe is None:
        gross_rev_trans_Stripe = 0

    if gross_rev_trans is None:
        gross_rev_trans = 0

    print ('gross', gross_rev_trans_VK, gross_rev_trans_Stripe, gross_rev_trans)

    total_gross_rev = gross_rev_trans_VK + gross_rev_trans_Stripe + gross_rev_trans

    return {'total_rev' : str(total_gross_rev / 100), 'current': 100, 'total': 100, 'statistic': 'get_gross_revenue', 'time_benchmark': (datetime.today() - START_TIME_FORM).total_seconds()}

# Selects gross revenue between selected dates
@app.route('/get-gross-revenue', methods=["POST"])
@basic_auth.required
@check_verified
def get_gross_revenue():
    if request.method == "POST":
        task = get_gross_revenue_task.apply_async([session['g_start_date'], session['g_end_date'], session['START_TIME_FORM']])
        return json.dumps({}), 202, {'Location': url_for('taskstatus_get_gross_revenue', task_id=task.id)}

例如,此任务始终在本地主机上返回100k,但在heroku上返回80k,我没有得到任何错误。它只是返回一个错误的值。那么这是怎么回事?该任务只需几秒钟即可完成。


注意:

在任务开始时我正在使用db_session.close(),因为在heroku "MySQL server has gone away"上出错。

这是我的芹菜配置:

CELERY_REDIS_MAX_CONNECTIONS=20
BROKER_POOL_LIMIT=None
CELERYD_WORKER_LOST_WAIT=20
CELERYD_MAX_TASKS_PER_CHILD=6
BROKER_TRANSPORT_OPTIONS = {'visibility_timeout': 18000} # 5 hours
CELERY_RESULT_DB_SHORT_LIVED_SESSIONS = True #useful if: For example, intermittent errors like (OperationalError) (2006, ‘MySQL server has gone away’)

其中一些配置现在可能无关紧要,因为我正在逐个执行任务(通过JS强制执行)。

这是我连接到MySQL的方式:

def checkout_listener(dbapi_con, con_record, con_proxy):
    try:
        try:
            dbapi_con.ping(False)
        except TypeError:
            dbapi_con.ping()
    except dbapi_con.OperationalError as exc:
        if exc.args[0] in (2006, 2013, 2014, 2045, 2055):
            raise DisconnectionError()
        else:
            raise

engine = create_engine(stats_config.DB_URI, convert_unicode=True, pool_size=100, pool_recycle=3600) 
event.listen(engine, 'checkout', checkout_listener)

db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()

在Heroku上,结果似乎10%~左右全部丢失。

编辑:

我尝试了一个非常大的查询,但是在heroku上,所有任务结果都略有偏离5%~,或者太高或太低。

0 个答案:

没有答案