Running Heroku background tasks with only 1 web dyno and 0 worker dynos

后端 未结 5 1858
不知归路
不知归路 2020-12-14 02:02

I have a Python Flask app on Heroku that serves web pages but also allows certain tasks to be launched which I believe would be best structured as background tasks. As such

5条回答
  •  死守一世寂寞
    2020-12-14 03:07

    I am currently running both my web and backend scheduler in Heroku using only 1 dyno.

    Idea is to provide one main python script for Heroku to start in 1 dyno. This script is used to start both the web server process(es) and the customer scheduler process(es). You can then define your jobs and add them to the custom scheduler.

    APScheduler is used in my case.

    This is what I did:

    in Procfile:

     web: python run_app.py    #the main startup script
    

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

    I am also using 4 Worker processes for serving the web from Gunicorn -- which runs perfectly fine.

    In gunicorn.conf.py:

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

    You may want to checkout this project as an example: Zjobs@Github

提交回复
热议问题