如何使 Laravel 队列在 aws beanstalk 中工作?

Ric*_*ick 6 amazon-ec2 queue worker-process elastic-beanstalk

我制作了一个 AWS Beanstalk 和 RDS 实例。我正在测试一个同步 FTP 和 S3 文件的项目。

我如何在 AWS Beanstalk 中制作典型php artisan queue:workphp artisan queue:listen工作?

我知道 Redis、ElastiCache 等。我还没有测试过它们。但我试图让它database只与驱动程序一起工作。

我也知道只访问 SSH,但是有没有办法在不使用 SSH 的情况下处理排队的作业?也许喜欢使用 .ebconfig?

小智 10

使用新的亚马逊 Linux AMI 2(推荐)

目前,日志文件不适用于 Linux AMI 2,只要更正此问题,配置就应该相同,因此我将创建它们的命令留在了那里。

自第一篇文章以来,eb 路线图宣布 PHP 平台已经更新,使事情变得更加容易。在 .ebextensions 文件下方还有一个需要设置的 .platform 文件。否则 nginx 将在所有路由上抛出 404 错误。

此映像使用 Systemd,这使得该过程变得更加容易,因为不再需要主管。不幸的services是,新图像尚不支持该关键字,因此必须使用该container_commands关键字启动和重新启动服务。

此文件包含我在每个生产环境中执行的所有命令,请记住将它们更改为适合您的需要:

\.ebextension\01-setup.config
Run Code Online (Sandbox Code Playgroud)
container_commands:
    01-no_dev:
        command: "composer.phar install --optimize-autoloader --no-dev"
    02-config_clear:
        command: "php artisan config:clear"
    03-route_cache:
        command: "php artisan route:cache"
    04-view_cache:
        command: "php artisan view:cache"
    05-migrate: 
        command: "php artisan migrate"
        leader_only: true
    06-queue_start:
        command: "systemctl restart laravel_worker"
files: 
    /opt/elasticbeanstalk/tasks/taillogs.d/laravel-logs.conf: 
        content: /var/app/current/storage/logs/laravel.log
        group: root
        mode: "000755"
        owner: root
    /etc/systemd/system/laravel_worker.service:
        mode: "000755"
        owner: root
        group: root
        content: |
            # Laravel queue worker using systemd
            # ----------------------------------
            #
            # /lib/systemd/system/queue.service
            #
            # run this command to enable service:
            # systemctl enable queue.service

            [Unit]
            Description=Laravel queue worker

            [Service]
            User=nginx
            Group=nginx
            Restart=always
            ExecStart=/usr/bin/nohup /usr/bin/php /var/www/html/laravel-project/artisan queue:work --daemon

            [Install]
            WantedBy=multi-user.target

Run Code Online (Sandbox Code Playgroud)

第二个文件:

\.platform\nginx\conf.d\elasticbeanstalk\laravel.conf
Run Code Online (Sandbox Code Playgroud)
location / {
    try_files $uri $uri/ /index.php?$query_string;
    gzip_static on;
}
Run Code Online (Sandbox Code Playgroud)

使用使用 amazon Linux AMI(上图)

最好的方法是运行 supervisor 来管理服务下的队列,以确保它即使在重新启动后也保持运行。

在 .ebextensions 中的配置文件中

1- 使用软件包安装主管。python 关键字在后台使用 pip 和 easy_install

packages:
    python:
        supervisor: []
Run Code Online (Sandbox Code Playgroud)

2- 创建主管配置文件:

files:
    /usr/local/etc/supervisord.conf:
        mode: "000755"
        owner: root
        group: root
        content: |
            [unix_http_server]
            file=/tmp/supervisor.sock   ; (the path to the socket file)

            [supervisord]
            logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
            logfile_maxbytes=50MB        ; (max main logfile bytes b4 rotation;default 50MB)
            logfile_backups=10           ; (num of main logfile rotation backups;default 10)
            loglevel=info                ; (log level;default info; others: debug,warn,trace)
            pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
            nodaemon=false               ; (start in foreground if true;default false)
            minfds=1024                  ; (min. avail startup file descriptors;default 1024)
            minprocs=200                 ; (min. avail process descriptors;default 200)

            [rpcinterface:supervisor]
            supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

            [supervisorctl]
            serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket

            [include]
            files = /etc/supervisor/conf.d/*.conf

            [inet_http_server]
            port = 127.0.0.1:9001
Run Code Online (Sandbox Code Playgroud)

3- 从laravel 文档中的配置主管部分创建主管进程文件:

files: 
    /etc/supervisor/conf.d/laravel-worker.conf: 
        content: |
            [program:laravel-worker]
            process_name=%(program_name)s_%(process_num)02d
            command=php /var/app/current/artisan queue:work database --sleep=3 --tries=3
            autostart=true
            autorestart=true
            ;user=root
            numprocs=1
            redirect_stderr=true
            ;stdout_logfile=/var/app/current/storage/logs/worker.log
            stopwaitsecs=3600
Run Code Online (Sandbox Code Playgroud)

4- 创建一个运行主管的服务。它与添加了 chkconfig 和 processname 行的答案相同。这些将允许我们稍后将其作为服务运行。

files:
    /etc/init.d/supervisord:
        mode: "000755"
        owner: root
        group: root
        content: |
            #!/bin/bash

            #chkconfig: 345 99 76
            # processname: supervisord

            # Source function library
            . /etc/rc.d/init.d/functions

            # Source system settings
            if [ -f /etc/sysconfig/supervisord ]; then
                . /etc/sysconfig/supervisord
            fi

            # Path to the supervisorctl script, server binary,
            # and short-form for messages.
            supervisorctl=/usr/local/bin/supervisorctl
            supervisord=${SUPERVISORD-/usr/local/bin/supervisord}
            prog=supervisord
            pidfile=${PIDFILE-/tmp/supervisord.pid}
            lockfile=${LOCKFILE-/var/lock/subsys/supervisord}
            STOP_TIMEOUT=${STOP_TIMEOUT-60}
            OPTIONS="${OPTIONS--c /usr/local/etc/supervisord.conf}"
            RETVAL=0

            start() {
                echo -n $"Starting $prog: "
                daemon --pidfile=${pidfile} $supervisord $OPTIONS
                RETVAL=$?
                echo
                if [ $RETVAL -eq 0 ]; then
                    touch ${lockfile}
                    $supervisorctl $OPTIONS status
                fi
                return $RETVAL
            }

            stop() {
                echo -n $"Stopping $prog: "
                killproc -p ${pidfile} -d ${STOP_TIMEOUT} $supervisord
                RETVAL=$?
                echo
                [ $RETVAL -eq 0 ] && rm -rf ${lockfile} ${pidfile}
            }

            reload() {
                echo -n $"Reloading $prog: "
                LSB=1 killproc -p $pidfile $supervisord -HUP
                RETVAL=$?
                echo
                if [ $RETVAL -eq 7 ]; then
                    failure $"$prog reload"
                else
                    $supervisorctl $OPTIONS status
                fi
            }

            restart() {
                stop
                start
            }

            case "$1" in
                start)
                    start
                    ;;
                stop)
                    stop
                    ;;
                status)
                    status -p ${pidfile} $supervisord
                    RETVAL=$?
                    [ $RETVAL -eq 0 ] && $supervisorctl $OPTIONS status
                    ;;
                restart)
                    restart
                    ;;
                condrestart|try-restart)
                    if status -p ${pidfile} $supervisord >&/dev/null; then
                    stop
                    start
                    fi
                    ;;
                force-reload|reload)
                    reload
                    ;;
                *)
                    echo $"Usage: $prog {start|stop|restart|condrestart|try-restart|force-reload|reload}"
                    RETVAL=2
                esac

                exit $RETVAL
Run Code Online (Sandbox Code Playgroud)

5- 创建所有文件后,运行以下命令以启动服务并添加它,以便对其进行管理:

commands:
  command-1: 
    command: "/etc/init.d/supervisord start"
  command-2:
    command: "chkconfig --add supervisord"
Run Code Online (Sandbox Code Playgroud)

6- 现在 services 关键字应该可以工作了,允许我们将 enabled 和 ensurerunning 标志设置为 true。

services:
    sysvinit:
        supervisord:
            enabled: "true"
            ensureRunning: "true"
            files: 
                - "/usr/local/etc/supervisord.conf"
Run Code Online (Sandbox Code Playgroud)

将所有这些放在您的 .config 文件中并部署以让队列工作


完整文件- 记得更改 chkconfig 编号并注意我正在运行migrate:fresh命令

packages:
    python:
        supervisor: []
container_commands:
    01-migrate: 
        command: "php artisan migrate:fresh --seed"
        cwd: /var/app/ondeck
        leader_only: true
files: 
    /opt/elasticbeanstalk/tasks/taillogs.d/laravel-logs.conf: 
        content: /var/app/current/storage/logs/laravel.log
        group: root
        mode: "000755"
        owner: root
    /etc/supervisor/conf.d/laravel-worker.conf: 
        content: |
            [program:laravel-worker]
            process_name=%(program_name)s_%(process_num)02d
            command=php /var/app/current/artisan queue:work database --sleep=3 --tries=3
            autostart=true
            autorestart=true
            ;user=root
            numprocs=1
            redirect_stderr=true
            ;stdout_logfile=/var/app/current/storage/logs/worker.log
            stopwaitsecs=3600
    /usr/local/etc/supervisord.conf:
        mode: "000755"
        owner: root
        group: root
        content: |
            [unix_http_server]
            file=/tmp/supervisor.sock   ; (the path to the socket file)

            [supervisord]
            logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
            logfile_maxbytes=50MB        ; (max main logfile bytes b4 rotation;default 50MB)
            logfile_backups=10           ; (num of main logfile rotation backups;default 10)
            loglevel=info                ; (log level;default info; others: debug,warn,trace)
            pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
            nodaemon=false               ; (start in foreground if true;default false)
            minfds=1024                  ; (min. avail startup file descriptors;default 1024)
            minprocs=200                 ; (min. avail process descriptors;default 200)

            [rpcinterface:supervisor]
            supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

            [supervisorctl]
            serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket

            [include]
            files = /etc/supervisor/conf.d/*.conf

            [inet_http_server]
            port = 127.0.0.1:9001
    /etc/init.d/supervisord:
        mode: "000755"
        owner: root
        group: root
        content: |
            #!/bin/bash

            #chkconfig: <number>
            # processname: supervisord

            # Source function library
            . /etc/rc.d/init.d/functions

            # Source system settings
            if [ -f /etc/sysconfig/supervisord ]; then
                . /etc/sysconfig/supervisord
            fi

            # Path to the supervisorctl script, server binary,
            # and short-form for messages.
            supervisorctl=/usr/local/bin/supervisorctl
            supervisord=${SUPERVISORD-/usr/local/bin/supervisord}
            prog=supervisord
            pidfile=${PIDFILE-/tmp/supervisord.pid}
            lockfile=${LOCKFILE-/var/lock/subsys/supervisord}
            STOP_TIMEOUT=${STOP_TIMEOUT-60}
            OPTIONS="${OPTIONS--c /usr/local/etc/supervisord.conf}"
            RETVAL=0

            start() {
                echo -n $"Starting $prog: "
                daemon --pidfile=${pidfile} $supervisord $OPTIONS
                RETVAL=$?
                echo
                if [ $RETVAL -eq 0 ]; then
                    touch ${lockfile}
                    $supervisorctl $OPTIONS status
                fi
                return $RETVAL
            }

            stop() {
                echo -n $"Stopping $prog: "
                killproc -p ${pidfile} -d ${STOP_TIMEOUT} $supervisord
                RETVAL=$?
                echo
                [ $RETVAL -eq 0 ] && rm -rf ${lockfile} ${pidfile}
            }

            reload() {
                echo -n $"Reloading $prog: "
                LSB=1 killproc -p $pidfile $supervisord -HUP
                RETVAL=$?
                echo
                if [ $RETVAL -eq 7 ]; then
                    failure $"$prog reload"
                else
                    $supervisorctl $OPTIONS status
                fi
            }

            restart() {
                stop
                start
            }

            case "$1" in
                start)
                    start
                    ;;
                stop)
                    stop
                    ;;
                status)
                    status -p ${pidfile} $supervisord
                    RETVAL=$?
                    [ $RETVAL -eq 0 ] && $supervisorctl $OPTIONS status
                    ;;
                restart)
                    restart
                    ;;
                condrestart|try-restart)
                    if status -p ${pidfile} $supervisord >&/dev/null; then
                    stop
                    start
                    fi
                    ;;
                force-reload|reload)
                    reload
                    ;;
                *)
                    echo $"Usage: $prog {start|stop|restart|condrestart|try-restart|force-reload|reload}"
                    RETVAL=2
                esac

                exit $RETVAL
                
commands:
  command-1: 
    command: "/etc/init.d/supervisord start"
  command-2:
    command: "chkconfig --add supervisord"
services:
    sysvinit:
        supervisord:
            enabled: "true"
            ensureRunning: "true"
            files: 
                - "/usr/local/etc/supervisord.conf"
Run Code Online (Sandbox Code Playgroud)


小智 0

执行此操作的理想方法是创建一个.ebextensions/01_queue_worker.config包含启动命令的内容的文件php artisan queue:work

就像是:

container_commands:
  01_queue_worker:
    command: "php artisan queue:work"
Run Code Online (Sandbox Code Playgroud)

现在,如果您不想在 Web 服务器上运行队列工作程序,而只想在单独的专用工作程序节点上运行,那么您可以创建一个名为“WORKER”的环境变量并将其设置为true. 然后在您的 ebextensions 配置文件中,您可以测试该变量,并且仅在“WORKER”变量为“true”时运行脚本。那看起来像这样:

container_commands:
  01_queue_worker:
    test: '[ "${WORKER}" == "true" ]'
    command: "php artisan queue:work"
Run Code Online (Sandbox Code Playgroud)

作为一般规则,每当您需要对 Elasticbeanstalk 上运行的内容进行任何修改时,请尝试查看ebextensions. 这是AWS用来进行修改的机制。