26

我在 Heroku 上有一个 Python Flask 应用程序,它提供网页服务,但也允许启动某些任务,我认为这些任务最好构造为后台任务。因此,我按照Herokurq教程设置后台任务。我的 Procfile 看起来像这样:

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

但是,我的流程目前是按比例缩放的web=1 worker=0。鉴于此后台进程不会经常运行,因此为它提供整个测功机然后为那么小的东西每月支付 34 美元对我来说似乎是不明智的。

问题:

  • 如果我保留worker在我的 Procfile 中声明的进程但将缩放保持在web=1 worker=0,我的排队进程最终会在我可用的网络测功机上运行吗?或者排队的进程永远不会运行?
  • 如果排队的进程永远不会运行,是否还有其他方法可以做到这一点,例如,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)
4

5 回答 5

13

修改Procfile为如下所示:

web: bin/web

现在创建bin目录,并创建如下所示的文件bin/web

#!/bin/bash
python app.py &
python worker.py

确保你给这个文件可执行权限:

$ chmod +x bin/web
于 2012-09-28T07:08:36.083 回答
3

我目前仅使用 1 个测功机在 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 个 Worker 进程从 Gunicorn 为网络提供服务——运行得非常好。

在 gunicorn.conf.py 中:

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

你可能想以这个项目为例:Zjobs@Github

于 2014-11-26T14:18:01.720 回答
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

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

于 2014-03-03T00:34:36.657 回答
0

在后台启动和运行进程:

档案:

run: python my_app.py

稍后,执行:

heroku ps:scale run=1
于 2020-04-29T12:30:33.707 回答
-2

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

heroku run worker
于 2012-09-28T14:58:23.930 回答