Сервер очередей Beanstalkd на Fedora

Введение

Сервер очередей выручает, когда нужно какие-то задачи выполнять параллельно от основного тела программы. Т.е. какую-то часть логики вынести из основной программы, если выполняемые действия не требуют немедленной синхронной обработки.

Установка

Установка обычным способом:
sudo dnf install beanstalkd
Я дополнительно поставил ещё несколько вспомогательных вещей:
sudo dnf install PyYAML supervisor
Запуск сервера производится через systemd:
sudo systemctl start beanstalkd.service
Добавить в автозапуск:
sudo systemctl enable beanstalkd.service
Проверить текущий статус:
sudo systemctl status beanstalkd.service
или
ps ax | grep beanstalkd
Краткая справка:
man beanstalkd
Настройки находятся в файле /etc/sysconfig/beanstalkd
Дополнительно я сразу поставил систему мониторинга "Admin console for Beanstalk queue server" по их инструкции (там есть описание и на русском языке) в каталог ~/vhosts/beanstalk-console/www. В каталоге ~/vhosts/beanstalk-console создал ещё каталоги tmp/, sess/, log/.

Настройки Apache

Этот пункт тут появился в те времена. когда я использовал Apache. Прописал виртуальный хост beanstalk-console.local в apache. /etc/httpd/conf.d/z-beanstalk-console.conf:

<VirtualHost *:80>
        DocumentRoot /home/oleg/vhosts/beanstalk-console/www/public
        ServerName beanstalk-console.local
        ServerAlias www.beanstalk-console.local
        ErrorLog /home/oleg/vhosts/beanstalk-console/log/apache_error.log
        CustomLog /home/oleg/vhosts/beanstalk-console/log/apache_access.log common
        <Directory /home/oleg/vhosts/beanstalk-console/www/public>
                Require local
                Options Includes Indexes FollowSymLinks
                AllowOverride All
                DirectoryIndex index.php
        </Directory>
        php_admin_value upload_tmp_dir /home/oleg/vhosts/beanstalk-console/tmp
        php_admin_value error_log /home/oleg/vhosts/beanstalk-console/log/php.log
        php_admin_value session.save_path /home/oleg/vhosts/beanstalk-console/sess
</VirtualHost>
И добавил в /etc/hosts строку

127.0.0.1 www.beanstalk-console.local beanstalk-console.local

Настройки SELinux для сайта

sudo semanage fcontext -a -t httpd_var_run_t "/home/oleg/vhosts/beanstalk-console/sess(/.*)?"
sudo semanage fcontext -a -t httpd_log_t "/home/oleg/vhosts/beanstalk-console/log(/.*)?"
sudo semanage fcontext -a -t httpd_tmp_t "/home/oleg/vhosts/beanstalk-console/tmp(/.*)?"
sudo semanage fcontext -a -t httpd_sys_content_t "/home/oleg/vhosts/beanstalk-console/www(/.*)?"
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/home/oleg/vhosts/beanstalk-console/www/storage.json"
sudo restorecon -R /home/oleg/vhosts/beanstalk-console/
sudo chown oleg:webmaster -R /home/oleg/vhosts/beanstalk-console/www
sudo chmod 775 -R /home/oleg/vhosts/beanstalk-console/www

Настройка для nginx

Вместо веб-сервера Apache, предпочитаю связку nginx + PHP-FPM. Тут как раз вариант настройки локального сайта на nginx. В файле /etc/nginx/sites-available/90_beanstalkd.local прописал:
server {
    listen       80;
    listen       [::]:80;
    server_name  beanstalk-console.local;
    access_log /home/oleg/vhosts/beanstalk-console/log/access.log;
    error_log /home/oleg/vhosts/beanstalk-console/log/error.log;
    root /home/oleg/vhosts/beanstalk-console/www/public/;

    include /etc/nginx/default.d/php.conf;

    # site root is redirected to the app boot script
    location = / {
        try_files @site @site;
    }

    # all other locations try other files first and go to our front controller if none of them exists
    location / {
        try_files $uri $uri/ @site;
    }

    # return 404 for all php files as we do have a front controller
    location ~ \.php$ {
       return 404;
    }

    location @site {
        fastcgi_pass php-fpm;
        include /etc/nginx/fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME $document_root/index.php;
        fastcgi_param HTTPS $https if_not_empty;
    }

    location ~ /\.(ht|svn|git) {
        deny  all;
    }
}
Теперь в браузере по адресу beanstalk-console.local видна административная консоль Beanstalkd:
Что дальше
Далее в нужном проекте подключаем библиотеку для работы с beanstald и выполняем обработку задач через очереди. А в настроенной консоли мониторим статус работы.
Имеет смысл внутри воркера делать ограничение на количество обрабатываемых задач (например, 50)  и автоматическое завершение. Одновременно с этим нужно настроить автоматический перезапуск воркера, чтобы он запускался вновь после завершения - для обработки следующей партии задач. Такое прерывание воркера позволит избежать проблем с возможной утечкой памяти или какими-то другими негативными последствиями долгой работы скрипта.
Пример сервиса systemd для перезапуска воркера

sudo nano /etc/systemd/system/stolplit-worker.service

[Unit]
Description=Worker queue for Stolplit's beanstalkd works
Requires=beanstalkd.service 
[Service]
Restart=always
RestartSec=3
ExecStart=/usr/bin/php /home/oleg/vhosts/site1/www/site1.ru/cron/worker/send_worker.php
User=webmaster
Group=webmaster
[Install]
WantedBy=multi-user.target
В данном случае будет задержка в 3 секунды перед перезапуском. В результате лог будет отображать сообщения о запуске/перезапусках
sudo journalctl -f
вот пример данных лога:

фев 20 13:50:35 oekhlakov.intaro systemd[1]: stolplit-worker.service: Service RestartSec=3s expired, scheduling restart.
фев 20 13:50:35 oekhlakov.intaro systemd[1]: stolplit-worker.service: Scheduled restart job, restart counter is at 4.
фев 20 13:50:35 oekhlakov.intaro systemd[1]: Stopped Worker queue for Stolplit's beanstalkd works.
фев 20 13:50:35 oekhlakov.intaro audit[1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=stolplit-worker comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
фев 20 13:50:35 oekhlakov.intaro audit[1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=stolplit-worker comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
фев 20 13:50:36 oekhlakov.intaro systemd[1]: Started Worker queue for Stolplit's beanstalkd works.
фев 20 13:50:36 oekhlakov.intaro audit[1]: SERVICE_START pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=stolplit-worker comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
фев 20 13:50:39 oekhlakov.intaro audit[1]: SERVICE_STOP pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='unit=stolplit-worker comm="systemd" exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
фев 20 13:50:42 oekhlakov.intaro systemd[1]: stolplit-worker.service: Service RestartSec=3s expired, scheduling restart.
фев 20 13:50:42 oekhlakov.intaro systemd[1]: stolplit-worker.service: Scheduled restart job, restart counter is at 5.
фев 20 13:50:42 oekhlakov.intaro systemd[1]: Stopped Worker queue for Stolplit's beanstalkd works.

Комментарии

Популярные сообщения из этого блога

Пропорциональное распределение суммы

Битрикс: своя геолокация

Битрикс: два способа отправить файл