仅使用1个web dyno和0个工作dynos运行Heroku后台任务

时间:2012-09-28 06:05:04

标签: python heroku redis

我在Heroku上有一个Python Flask应用程序,用于提供网页,但也允许启动某些任务,我认为这些任务最适合作为后台任务。因此,我遵循Heroku rq tutorial来设置后台任务。我的Procfile如下所示:

web: python app.py
worker: python worker.py

但是,我的流程目前已缩放web=1 worker=0。鉴于这种背景过程不会经常运行,我似乎不明智地为它配置一个完整的dyno然后为那么小的东西支付34美元/月。

问题:

  • 如果我将worker进程保留在我的Procfile中,但保持缩放为web=1 worker=0,我的排队进程最终会在我的可用网络dyno上运行吗?或排队的进程永远不会运行?
  • 如果排队的进程永远不会运行,是否有其他方法可以做到这一点,例如,在我的网络应用中使用twisted来异步运行任务?

其他信息

worker.py看起来像这样:

import os
import redis
from rq import Worker, Queue, Connection

listen = ['high', 'default', 'low']

redis_url = os.getenv('REDISTOGO_URL', 'redis://localhost:6379')

conn = redis.from_url(redis_url)

if __name__ == '__main__':
    with Connection(conn):
        worker = Worker(map(Queue, listen))
        worker.work()

主进程中排队进程的逻辑如下所示:

from rq import Queue
from worker import conn
q = Queue(connection=conn)

q.enqueue(myfunction, myargument)

5 个答案:

答案 0 :(得分:12)

$ cat Procfile
web: bin/web

$ cat bin/web
python app.py &
python worker.py

答案 1 :(得分:3)

我目前只使用1个dyno在Heroku中运行我的Web和后端调度程序。

想法是为Heroku提供一个主要的python脚本,以1 dyno开始。此脚本用于启动Web服务器进程和客户调度程序进程。 然后,您可以定义作业并将其添加到自定义计划程序。

在我的案例中使用

APScheduler

这就是我所做的:

在Procfile中:

 web: python run_app.py    #the main startup script
在run_app.py中

# All the required imports
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
from apscheduler.triggers.cron import CronTrigger
from run_housekeeping import run_housekeeping
from apscheduler.schedulers.background import BackgroundScheduler
import os

def run_web_script():
    # start the gunicorn server with custom configuration
    # You can also using app.run() if you want to use the flask built-in server -- be careful about the port
    os.system('gunicorn -c gunicorn.conf.py web.jobboard:app --debug')  

def start_scheduler():

     # define a background schedule 
     # Attention: you cannot use a blocking scheduler here as that will block the script from proceeding.
     scheduler = BackgroundScheduler()

     # define your job trigger
     hourse_keeping_trigger = CronTrigger(hour='12', minute='30')

     # add your job
     scheduler.add_job(func=run_housekeeping, trigger=hourse_keeping_trigger)

     # start the scheduler
     scheduler.start()


def run():
    start_scheduler()
    run_web_script()

if __name__ == '__main__':
    run()

我也使用了4个工作进程来为Gunicorn提供网络服务 - 运行得非常好。

在gunicorn.conf.py中:

loglevel = 'info'
errorlog = '-'
accesslog = '-'
workers = 4

您可能想结帐此项目作为示例:Zjobs@Github

答案 2 :(得分:1)

您可以使用流程管理器,例如godmonit

有了上帝,您可以像这样设置配置

God.watch do |w|
  w.name = "app"
  w.start = "python app.py"
  w.keepalive
end

God.watch do |w|
  w.name = "worker"
  w.start = "python worker.py"
  w.keepalive
end

然后将其放入Procfile

god -c path/to/config.god -D

默认情况下,如果进程崩溃,它会自动重新启动进程,如果内存使用率过高,您可以将其配置为重新启动应用程序。查看文档。

答案 3 :(得分:0)

要在后台启动并运行进程,请执行以下操作:

Procfile:

run: python my_app.py

然后执行:

heroku ps:scale run=1

答案 4 :(得分:-2)

您应该查看Heroku Scheduler它将允许您按计划的时间间隔(例如每10分钟)运行一项特定任务。如果您已经有工作人员设置,则可以添加:

heroku run worker