How to run a celery worker with Django app scalable by AWS Elastic Beanstalk?

前端 未结 3 1767
庸人自扰
庸人自扰 2020-12-02 12:47

How to use Django with AWS Elastic Beanstalk that would also run tasks by celery on main node only?

3条回答
  •  一整个雨季
    2020-12-02 13:08

    This is how I extended the answer by @smentek to allow for multiple worker instances and a single beat instance - same thing applies where you have to protect your leader. (I still don't have an automated solution for that yet).

    Please note that envvar updates to EB via the EB cli or the web interface are not relflected by celery beat or workers until app server restart has taken place. This caught me off guard once.

    A single celery_configuration.sh file outputs two scripts for supervisord, note that celery-beat has autostart=false, otherwise you end up with many beats after an instance restart:

    # get django environment variables
    celeryenv=`cat /opt/python/current/env | tr '\n' ',' | sed 's/export //g' | sed 's/$PATH/%(ENV_PATH)s/g' | sed 's/$PYTHONPATH//g' | sed 's/$LD_LIBRARY_PATH//g' | sed 's/%/%%/g'`
    celeryenv=${celeryenv%?}
    
    # create celery beat config script
    celerybeatconf="[program:celeryd-beat]
    ; Set full path to celery program if using virtualenv
    command=/opt/python/run/venv/bin/celery beat -A lexvoco --loglevel=INFO --workdir=/tmp -S django --pidfile /tmp/celerybeat.pid
    
    directory=/opt/python/current/app
    user=nobody
    numprocs=1
    stdout_logfile=/var/log/celery-beat.log
    stderr_logfile=/var/log/celery-beat.log
    autostart=false
    autorestart=true
    startsecs=10
    
    ; Need to wait for currently executing tasks to finish at shutdown.
    ; Increase this if you have very long running tasks.
    stopwaitsecs = 10
    
    ; When resorting to send SIGKILL to the program to terminate it
    ; send SIGKILL to its whole process group instead,
    ; taking care of its children as well.
    killasgroup=true
    
    ; if rabbitmq is supervised, set its priority higher
    ; so it starts first
    priority=998
    
    environment=$celeryenv"
    
    # create celery worker config script
    celeryworkerconf="[program:celeryd-worker]
    ; Set full path to celery program if using virtualenv
    command=/opt/python/run/venv/bin/celery worker -A lexvoco --loglevel=INFO
    
    directory=/opt/python/current/app
    user=nobody
    numprocs=1
    stdout_logfile=/var/log/celery-worker.log
    stderr_logfile=/var/log/celery-worker.log
    autostart=true
    autorestart=true
    startsecs=10
    
    ; Need to wait for currently executing tasks to finish at shutdown.
    ; Increase this if you have very long running tasks.
    stopwaitsecs = 600
    
    ; When resorting to send SIGKILL to the program to terminate it
    ; send SIGKILL to its whole process group instead,
    ; taking care of its children as well.
    killasgroup=true
    
    ; if rabbitmq is supervised, set its priority higher
    ; so it starts first
    priority=999
    
    environment=$celeryenv"
    
    # create files for the scripts
    echo "$celerybeatconf" | tee /opt/python/etc/celerybeat.conf
    echo "$celeryworkerconf" | tee /opt/python/etc/celeryworker.conf
    
    # add configuration script to supervisord conf (if not there already)
    if ! grep -Fxq "[include]" /opt/python/etc/supervisord.conf
      then
      echo "[include]" | tee -a /opt/python/etc/supervisord.conf
      echo "files: celerybeat.conf celeryworker.conf" | tee -a /opt/python/etc/supervisord.conf
    fi
    
    # reread the supervisord config
    /usr/local/bin/supervisorctl -c /opt/python/etc/supervisord.conf reread
    # update supervisord in cache without restarting all services
    /usr/local/bin/supervisorctl -c /opt/python/etc/supervisord.conf update
    

    Then in container_commands we only restart beat on leader:

    container_commands:
      # create the celery configuration file
      01_create_celery_beat_configuration_file:
        command: "cat .ebextensions/files/celery_configuration.sh > /opt/elasticbeanstalk/hooks/appdeploy/post/run_supervised_celeryd.sh && chmod 744 /opt/elasticbeanstalk/hooks/appdeploy/post/run_supervised_celeryd.sh && sed -i 's/\r$//' /opt/elasticbeanstalk/hooks/appdeploy/post/run_supervised_celeryd.sh"
      # restart celery beat if leader
      02_start_celery_beat:
        command: "/usr/local/bin/supervisorctl -c /opt/python/etc/supervisord.conf restart celeryd-beat"
        leader_only: true
      # restart celery worker
      03_start_celery_worker:
        command: "/usr/local/bin/supervisorctl -c /opt/python/etc/supervisord.conf restart celeryd-worker"
    

提交回复
热议问题