Перейти до вмісту

Робочі процеси

Робочі процеси — це довготривалі процеси, які опитують базу даних на наявність завдань, що очікують на виконання, виконують їх і просувають робочі потоки далі. Команда wp queuety work працює всередині WP-CLI, а сама черга обробляється безпосередньо з MySQL через найкращий доступний драйвер БД Queuety.

Плагін також встановлює стандартне резервне завдання WordPress cron, яке запускається раз на хвилину для середовищ без доступу до оболонки. На цій сторінці описано виділені робочі процеси WP-CLI — рекомендований режим розгортання для вищої пропускної здатності.

Запуск робочого процесу

Командна оболонка
wp queuety work

Це запускає один робочий процес у черзі default. Він працює в циклі: отримує завдання, виконує його та повторює цикл. Коли черга порожня, він чекає QUEUETY_WORKER_SLEEP секунд (за замовчуванням: 1), перш ніж знову перевірити її.

Параметри

Параметр Опис
--queue=<queue> Queue(s) для обробки; розділяйте назви комами, щоб указати порядок пріоритету (за замовчуванням: default)
--once Обробити не більше одного завдання та завершити роботу
--workers=<n> Створити N дочірніх робочих процесів (потрібні розширення pcntl і posix)
--min-workers=<n> Мінімальна кількість робочих процесів в адаптивному пулі. Потрібен --max-workers
--max-workers=<n> Максимальна кількість робочих процесів в адаптивному пулі
Командна оболонка
# Process a specific queue
wp queuety work --queue=emails

# Process at most one job and exit
wp queuety work --once

# Run 4 concurrent workers
wp queuety work --workers=4

# Scale between 2 and 6 workers as backlog changes
wp queuety work --queue=providers --min-workers=2 --max-workers=6

Пріоритети кількох черг

Один робочий процес може обробляти кілька черг у порядку пріоритету. Передайте --queue список назв черг, розділених комами:

Командна оболонка
wp queuety work --queue=critical,default,low

Робочий процес намагається отримати завдання з кожної черги у вказаному порядку. Спершу він перевіряє critical. Якщо в critical є завдання, він його обробляє. Якщо critical порожня, він переходить до default, а потім до low. Це означає, що черги з вищим пріоритетом завжди спорожнюються раніше за черги з нижчим пріоритетом.

Як працює порядок пріоритетів

На кожній ітерації робочий процес намагається отримати завдання з першої черги у списку. Якщо вона порожня або призупинена, він переходить до наступної черги й так триває, доки не знайде завдання або не перевірить усі черги. Якщо ніде немає завдань, робочий процес чекає та повторює спробу. Це модель суворих пріоритетів: постійний потік завдань critical блокуватиме черги default і low. Якщо чергам із нижчим пріоритетом потрібна гарантована пропускна здатність, використовуйте для них окремі робочі процеси.

Використання кількох черг у PHP

Методи Worker::run() і Worker::flush() приймають рядок або масив:

PHP
// Comma-separated string
Queuety::worker()->run( 'critical,default,low' );

// Array
Queuety::worker()->run( [ 'critical', 'default', 'low' ] );

// flush() also supports multi-queue
$count = Queuety::worker()->flush( 'critical,default,low' );

Стратегії розгортання

Окремі робочі процеси для кожної черги дають повний контроль над паралелізмом та ізоляцією. Кожна черга отримує власний пул робочих процесів process(es), і інші черги не можуть перешкоджати її обробці:

Ini
[program:queuety-critical]
command=wp queuety work --queue=critical
numprocs=4

[program:queuety-default]
command=wp queuety work --queue=default
numprocs=2

[program:queuety-low]
command=wp queuety work --queue=low
numprocs=1

Порядок пріоритетів з одним робочим процесом простіше підтримувати; такий підхід добре працює, якщо черги з нижчим пріоритетом можуть чекати:

Ini
[program:queuety-worker]
command=wp queuety work --queue=critical,default,low
numprocs=2

Також можна поєднати обидва підходи: виділити окремі робочі процеси для critical, щоб гарантувати пропускну здатність, а для всього іншого використовувати робочий процес із пріоритетним порядком:

Ini
[program:queuety-critical]
command=wp queuety work --queue=critical
numprocs=2

[program:queuety-fallback]
command=wp queuety work --queue=default,low
numprocs=2

Допуск з урахуванням ресурсів

Робочі процеси не просто отримують наступний рядок із завданням, що очікує на виконання. Перш ніж розпочати отримане завдання, Queuety може виконати попередні перевірки допуску на основі групи паралелізму завдання та недавнього профілю виконання відповідного обробника.

Ширший опис цієї моделі, зокрема її зв’язок із метаданими завдань і бюджетами робочих потоків, дивіться в розділі Керування ресурсами.

Група паралелізму встановлює спільне обмеження для кількох обробників або класів завдань. Якщо кільком ресурсомістким постачальникам призначити однакову групу й обмеження, робочий процес відпустить щойно отримане завдання замість того, щоб запускати його, коли буде досягнуто ліміту групи. Це не дає завданням із незалежних черг одночасно перевантажити одну нижчестоящу систему лише через наявність кількох вільних робочих процесів.

Журнали нещодавніх виконань також формують простий профіль допуску. Коли допуск з урахуванням ресурсів увімкнено, Queuety перевіряє середню тривалість і пікове використання пам’яті обробником, який має запуститися. Якщо поточний робочий процес уже наближається до встановленого ліміту пам’яті, черга або група постачальників уже вичерпала свій зважений бюджет, у поточному контейнері, схоже, недостатньо вільної пам’яті для обробника з таким профілем або виконання на кшталт --once наближається до свого часового ліміту, Queuety відкладає завдання замість того, щоб починати роботу, яка, імовірно, не завершиться належним чином.

Політику вмикають у визначенні роботи, а не в команді запуску робочого процесу:

PHP
class CallProviderStep implements \Queuety\Step {
    public function handle( array $state ): array {
        // ...
    }

    public function config(): array {
        return [
            'concurrency_group' => 'providers',
            'concurrency_limit' => 3,
            'cost_units' => 5,
        ];
    }
}

Ті самі метадані можна додати до класів завдань, доступних для надсилання, за допомогою відкритих властивостей або до окремого надсилання через PendingJob::concurrency_group() і PendingJob::cost_units().

Профіль допуску на стороні робочого процесу налаштовується такими константами:

Константа Опис
QUEUETY_RESOURCE_ADMISSION Увімкнути або вимкнути перевірки допуску на основі профілю
QUEUETY_RESOURCE_PROFILE_WINDOW_MINUTES Період ретроспективи для формування профілів нещодавніх виконань обробників
QUEUETY_RESOURCE_PROFILE_TTL Час життя кешу профілів нещодавніх виконань обробників
QUEUETY_RESOURCE_MEMORY_HEADROOM_MB Резерв пам’яті, який потрібно залишити перед допуском наступного завдання
QUEUETY_RESOURCE_SYSTEM_MEMORY_AWARENESS Увімкнути або вимкнути приблизні перевірки пам’яті контейнера чи хоста
QUEUETY_RESOURCE_SYSTEM_MEMORY_HEADROOM_MB Резерв системної пам’яті, який потрібно залишити перед допуском наступного завдання
QUEUETY_RESOURCE_QUEUE_COST_BUDGETS Зважені бюджети вартості за назвою черги
QUEUETY_RESOURCE_GROUP_COST_BUDGETS Зважені бюджети вартості за concurrency_group
QUEUETY_RESOURCE_TIME_HEADROOM_MS Резерв часу для одноразового запуску робочого процесу

Життєвий цикл робочого процесу

Робочий процес завершується коректно після завершення поточного завдання, якщо виконується будь-яка з таких умов:

Умова Налаштування
Максимальна кількість оброблених завдань QUEUETY_WORKER_MAX_JOBS (за замовчуванням: 1000)
Перевищено ліміт пам’яті QUEUETY_WORKER_MAX_MEMORY (за замовчуванням: 128 МБ)

Після зупинки робочий процес коректно завершується. У виробничому середовищі менеджер процесів автоматично перезапускає його.

Коректна обробка сигналів поки що не підтримується (#4). Окремий процес wp queuety work не встановлює обробник сигналів, тож SIGTERM або SIGINT (Ctrl+C) негайно завершує його, навіть посеред виконання завдання. Це завдання залишається в стані processing, доки після QUEUETY_STALE_TIMEOUT секунд його не скине механізм відновлення завислих завдань. Тому переконайтеся, що обробники безпечно запускати повторно. Пул робочих процесів пересилає SIGTERM дочірнім процесам, але вони не реагують на нього, тож пул продовжує працювати, доки не зупиниться з однієї з наведених вище причин. Щоб зупинити пул, налаштуйте менеджер процесів надсилати SIGKILL після завершення часу очікування на зупинку.

Паралелізм кількох робочих процесів

Прапорець --workers=N створює N дочірніх процесів за допомогою pcntl_fork(). Кожен дочірній процес встановлює власне підключення до бази даних і обробляє завдання незалежно. Батьківський процес контролює дочірні та перезапускає ті, що аварійно завершилися.

Командна оболонка
wp queuety work --queue=default --workers=4

Вимоги: Мають бути встановлені розширення pcntl і posix PHP (без pcntl команда завершується помилкою «pcntl extension is required for --workers=N.»), а кожен дочірній процес використовує власне підключення до бази даних, тому параметр MySQL max_connections потрібно налаштувати з урахуванням пулу. Для адаптивних пулів (--min-workers/--max-workers) діють ті самі вимоги.

Адаптивні пули робочих процесів

Адаптивні пули підтримують мінімальну кількість постійно готових робочих процесів, а потім збільшують або зменшують її в межах заданого діапазону:

Командна оболонка
wp queuety work --queue=providers --min-workers=2 --max-workers=6

Батьківський процес стежить за кількістю завдань, доступних для отримання, у вибраному наборі черг і коригує кількість дочірніх процесів відповідно до цього навантаження, не перевищуючи заданого максимуму. Коли черга затихає, пул чекає протягом періоду очікування бездіяльності, перш ніж зменшити кількість процесів, щоб короткі сплески не спричиняли негайної зміни списку процесів.

Збільшення масштабу відбувається обережно. Коли Queuety може отримувати дані про пам’ять контейнера або хоста, він відмовляється додавати дочірні процеси, якщо вільної пам’яті недостатньо для повного набору ресурсів ще одного робочого процесу.

Цикл масштабування на стороні батьківського процесу налаштовується так:

Константа Опис
QUEUETY_WORKER_POOL_SCALE_INTERVAL Як часто батьківський процес узгоджує розмір пулу
QUEUETY_WORKER_POOL_IDLE_GRACE Як довго черга має залишатися тихою перед зменшенням масштабу

Відновлення завислих завдань

Якщо робочий процес аварійно завершується під час обробки завдання, завдання залишається у стані processing. Довготривалий робочий процес приблизно раз на хвилину перевіряє, чи є завдання, що перебувають у стані processing довше ніж QUEUETY_STALE_TIMEOUT секунд. Для завислого завдання, у якого залишилися спроби, повторне виконання планується після затримки між спробами; завдання, у якого всі спроби вичерпано, переміщується до відкладених, а відповідний робочий потік позначається як невдалий. Робочі процеси --once і резервний механізм WP-Cron такої перевірки не виконують.

Відновіть завислі завдання вручну:

Командна оболонка
wp queuety recover

Режим обробки всіх завдань

Обробіть усі завдання, що очікують на виконання, і завершіть роботу. Зручно для тестування або одноразової пакетної обробки:

Командна оболонка
wp queuety flush
wp queuety flush --queue=emails

Розгортання у виробничому середовищі

Для виробничого середовища використовуйте менеджер процесів, щоб робочі процеси працювали постійно. Ось два поширені варіанти.

Supervisord

Ini
[program:queuety-default]
command=wp queuety work --queue=default
directory=/var/www/html
autostart=true
autorestart=true
numprocs=2
process_name=%(program_name)s_%(process_num)02d
stdout_logfile=/var/log/queuety-default.log
stderr_logfile=/var/log/queuety-default-error.log

[program:queuety-emails]
command=wp queuety work --queue=emails
directory=/var/www/html
autostart=true
autorestart=true
numprocs=1
stdout_logfile=/var/log/queuety-emails.log
stderr_logfile=/var/log/queuety-emails-error.log

Systemd

Ini
[Unit]
Description=Queuety Worker (default queue)
After=mysql.service

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/html
ExecStart=/usr/local/bin/wp queuety work --queue=default
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Увімкніть і запустіть:

Командна оболонка
sudo systemctl enable queuety-worker
sudo systemctl start queuety-worker

Поради щодо розгортання

Запускайте окремих воркерів для окремих черг, якщо потрібна краща ізоляція. Використовуйте --workers=N, коли навантаження обмежене CPU, а якщо переважають операції введення-виведення — надавайте перевагу окремим воркерам під наглядом. Установіть QUEUETY_WORKER_MAX_JOBS, щоб періодично перезапускати воркери й звільняти пам’ять, і стежте за кількістю buried через вебхуки або метрики.