run logs log cli app python heroku redis

python - logs - Ejecución de tareas en segundo plano de Heroku con solo 1 web dyno y 0 trabajadores.



heroku restart app (4)

Tengo una aplicación de Python Flask en Heroku que sirve páginas web, pero también permite que se inicien ciertas tareas que creo que sería mejor estructuradas como tareas de fondo. Como tal, he seguido el tutorial de Heroku rq para configurar tareas en segundo plano. Mi Procfile se ve así:

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

Sin embargo, mis procesos están actualmente escalados web=1 worker=0 . Dado que este proceso en segundo plano no se ejecutará muy a menudo, no me parece sensato proporcionarle un dinamo completo y luego pagar los $ 34 / mes por algo tan pequeño.

Pregunta:

  • Si dejo el proceso de worker declarado en mi Procfile pero mantengo la escala en web=1 worker=0 , ¿mis procesos en cola se ejecutarán en mi sitio web disponible? ¿O nunca se ejecutarán los procesos en cola?
  • Si los procesos en cola nunca se ejecutarán, ¿hay alguna otra forma de hacerlo, por ejemplo, utilizando twisted en mi aplicación web para ejecutar las tareas de forma asíncrona?

Información Adicional

worker.py ve así:

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

La lógica en la aplicación principal que pone en cola un proceso se ve así:

from rq import Queue from worker import conn q = Queue(connection=conn) q.enqueue(myfunction, myargument)


Actualmente estoy ejecutando mi web y mi programador backend en Heroku usando solo 1 dinamo.

La idea es proporcionar un script de Python principal para que Heroku comience en 1 dinamómetro. Esta secuencia de comandos se utiliza para iniciar tanto los procesos del servidor web como los procesos del programador del cliente. A continuación, puede definir sus trabajos y agregarlos al programador personalizado.

APScheduler se utiliza en mi caso.

Esto es lo que hice:

en Procfile:

web: python run_app.py #the main startup script

en el 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()

También estoy usando 4 procesos de trabajo para servir la web desde Gunicorn, que funciona perfectamente bien.

En gunicorn.conf.py:

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

Es posible que desee revisar este proyecto como ejemplo: Zjobs@Github


Debería echar un vistazo a Heroku Scheduler, que le permitirá ejecutar una tarea específica en un intervalo programado, como cada 10 minutos. Si ya tiene la configuración de trabajador, podría agregar:

heroku run worker


Podrías usar un gestor de procesos como god o monit .

Con dios, puedes configurar tu configuración como tal

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

Entonces pones esto en tu Procfile

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

De forma predeterminada, se reinicia automáticamente el proceso si se bloquea, y puede configurarlo para reiniciar la aplicación si el uso de la memoria es demasiado alto. Echa un vistazo a la documentación.


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