Pular para o conteúdo

Workers

Workers são processos de longa duração que consultam o banco de dados em busca de tarefas pendentes, executam-nas e avançam os fluxos de trabalho. O comando wp queuety work é executado dentro de WP-CLI enquanto a fila é reivindicada diretamente de MySQL pelo melhor driver de banco de dados Queuety disponível.

O plugin também instala uma alternativa padrão de WordPress cron, executada uma vez por minuto, para ambientes sem acesso ao shell. Esta página aborda workers WP-CLI dedicados, o modo de implantação recomendado para maior throughput.

Iniciando um worker

Shell
wp queuety work

Isso inicia um único worker na fila default. Ele executa em loop: reivindica uma tarefa, executa-a e repete. Quando a fila está vazia, aguarda QUEUETY_WORKER_SLEEP segundos (padrão: 1) antes de consultá-la novamente.

Opções

Opção Descrição
--queue=<queue> Queue(s) a processar, separados por vírgulas para definir a ordem de prioridade (padrão: default)
--once Processa no máximo uma tarefa e encerra
--workers=<n> Cria N processos worker (requer as extensões pcntl e posix)
--min-workers=<n> Número mínimo de workers para um pool adaptável. Requer --max-workers
--max-workers=<n> Número máximo de workers para um pool adaptável
Shell
# 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

Prioridades entre várias filas

Um único worker pode processar várias filas em ordem de prioridade. Passe uma lista de nomes de filas separados por vírgulas para --queue:

Shell
wp queuety work --queue=critical,default,low

O worker tenta reivindicar uma tarefa de cada fila na ordem informada. Ele verifica critical primeiro. Se critical tiver uma tarefa, ele a processa. Se critical estiver vazia, passa para default e, em seguida, para low. Isso significa que as filas de maior prioridade são sempre esvaziadas antes das de menor prioridade.

Como funciona a ordem de prioridade

A cada iteração, o worker tenta reivindicar uma tarefa da primeira fila da lista. Se essa fila estiver vazia ou pausada, passa para a próxima e continua até encontrar uma tarefa ou percorrer a lista toda. Se nenhuma tarefa for encontrada, o worker aguarda e tenta novamente. Esse modelo de prioridade estrita significa que um fluxo constante de tarefas critical deixará as filas default e low sem processamento. Se filas de menor prioridade precisarem de throughput garantido, use workers dedicados.

Usando várias filas em PHP

Os métodos Worker::run() e Worker::flush() aceitam uma string ou um array:

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' );

Estratégias de implantação

Workers dedicados por fila oferecem controle total sobre a concorrência e o isolamento. Cada fila recebe seu próprio process(es) de worker e não pode ficar sem processamento por causa de outras filas:

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

A ordem de prioridade com um único worker é mais simples de gerenciar e funciona bem quando filas de menor prioridade podem tolerar atrasos:

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

Você também pode combinar as duas abordagens: workers dedicados para critical garantem o throughput, enquanto um worker com filas ordenadas por prioridade processa todo o restante:

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

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

Admissão com base nos recursos

Workers fazem mais do que simplesmente reivindicar a próxima linha pendente. Antes de iniciar uma tarefa reivindicada, Queuety pode aplicar verificações gerais de admissão com base no grupo de concorrência da tarefa e no perfil recente de execução daquele handler.

Para conhecer o modelo mais amplo, incluindo como ele se relaciona aos metadados de tarefas e aos orçamentos dos fluxos de trabalho, consulte Gerenciamento de recursos.

Um grupo de concorrência permite que vários handlers ou classes de tarefas compartilhem um limite. Se você atribuir o mesmo grupo e limite a vários provedores que consomem muitos recursos, o worker liberará o trabalho recém-reivindicado em vez de iniciá-lo quando o grupo atingir o limite. Isso impede que filas independentes sobrecarreguem um mesmo sistema downstream só porque há vários workers ociosos.

Os registros de execução recentes também alimentam um perfil simples de admissão. Quando a admissão por recursos está ativada, Queuety consulta a duração média recente e o pico de memória do handler que está prestes a executar. Se o worker atual já estiver perto do limite de memória configurado, uma fila ou grupo de provedores já tiver atingido seu orçamento ponderado, o contêiner atual aparentemente não tiver memória livre suficiente para o perfil observado do handler ou uma execução no estilo --once estiver perto do seu limite de tempo, Queuety adia a tarefa em vez de iniciar um trabalho com poucas chances de terminar corretamente.

Você ativa a política na definição do trabalho, e não no comando do worker:

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,
        ];
    }
}

Os mesmos metadados podem ser atribuídos a classes de tarefa despacháveis por meio de propriedades públicas ou a um despacho individual usando PendingJob::concurrency_group() e PendingJob::cost_units().

O perfil de admissão do worker é controlado por estas constantes:

Constante Descrição
QUEUETY_RESOURCE_ADMISSION Ativa ou desativa verificações de admissão baseadas em perfil
QUEUETY_RESOURCE_PROFILE_WINDOW_MINUTES Período de consulta usado para criar perfis recentes de handlers
QUEUETY_RESOURCE_PROFILE_TTL TTL do cache dos perfis recentes de handlers
QUEUETY_RESOURCE_MEMORY_HEADROOM_MB Margem de memória reservada antes de admitir outra tarefa
QUEUETY_RESOURCE_SYSTEM_MEMORY_AWARENESS Ativa ou desativa verificações de melhor esforço da memória do contêiner ou host
QUEUETY_RESOURCE_SYSTEM_MEMORY_HEADROOM_MB Margem de memória do sistema reservada antes de admitir outra tarefa
QUEUETY_RESOURCE_QUEUE_COST_BUDGETS Orçamentos de custo ponderado definidos por nome de fila
QUEUETY_RESOURCE_GROUP_COST_BUDGETS Orçamentos de custo ponderado definidos por concurrency_group
QUEUETY_RESOURCE_TIME_HEADROOM_MS Margem de tempo reservada para execuções de worker em uma única execução

Ciclo de vida do worker

Um worker é encerrado de forma gradual, após concluir a tarefa atual, quando qualquer uma destas condições é atendida:

Condição Configuração
Número máximo de tarefas processadas QUEUETY_WORKER_MAX_JOBS (padrão: 1000)
Limite de memória excedido QUEUETY_WORKER_MAX_MEMORY (padrão: 128 MB)

Após parar, o worker é encerrado corretamente. Em produção, um gerenciador de processos o reinicia automaticamente.

Os sinais ainda não são tratados de forma gradual (#4). Um processo wp queuety work único não instala um handler de sinal; portanto, SIGTERM ou SIGINT (Ctrl+C) o encerra imediatamente, mesmo durante uma tarefa. Essa tarefa permanece processing até que a recuperação de tarefas obsoletas a redefina após QUEUETY_STALE_TIMEOUT segundos; por isso, mantenha os handlers seguros para novas tentativas. Um pool de workers encaminha SIGTERM aos processos filhos, mas eles não agem sobre o sinal. Assim, o pool continua em execução até que parem por um dos motivos acima. Para interromper um pool, configure um tempo limite de parada no gerenciador de processos; depois desse prazo, ele enviará SIGKILL.

Concorrência com vários workers

A opção --workers=N cria N processos filhos usando pcntl_fork(). Cada filho cria sua própria conexão com o banco de dados e processa tarefas de forma independente. O processo pai monitora os filhos e reinicia os que falharem.

Shell
wp queuety work --queue=default --workers=4

Requisitos: As extensões pcntl e posix PHP precisam estar instaladas (sem pcntl, o comando falha com "pcntl extension is required for --workers=N."), e cada filho usa sua própria conexão com o banco de dados; portanto, a configuração MySQL max_connections precisa comportar o pool. Pools adaptáveis (--min-workers/--max-workers) têm os mesmos requisitos.

Pools de workers adaptáveis

Os pools adaptáveis mantêm um número mínimo de workers prontos e aumentam ou diminuem dentro do intervalo configurado:

Shell
wp queuety work --queue=providers --min-workers=2 --max-workers=6

O processo pai monitora o backlog reivindicável no conjunto de filas selecionado e ajusta o número de processos filhos de acordo com esse backlog, respeitando o máximo configurado. Quando a fila fica mais tranquila, o pool aguarda o período de tolerância à ociosidade antes de reduzir o número de workers, evitando que picos breves alterem imediatamente a lista de processos.

O aumento ainda é conservador. Quando Queuety consegue ler as métricas de memória do contêiner ou host, ele se recusa a adicionar processos filhos se não houver memória livre suficiente para outro worker completo.

O loop de ajuste de escala do processo pai é controlado por:

Constante Descrição
QUEUETY_WORKER_POOL_SCALE_INTERVAL Intervalo entre ajustes do tamanho do pool pelo processo pai
QUEUETY_WORKER_POOL_IDLE_GRACE Tempo durante o qual o backlog precisa permanecer reduzido antes de diminuir o pool

Recuperação de tarefas obsoletas

Se um worker falhar durante o processamento de uma tarefa, ela ficará com o status processing. Um worker de longa duração verifica aproximadamente uma vez por minuto se há tarefas que permanecem em processing por mais de QUEUETY_STALE_TIMEOUT segundos. Uma tarefa obsoleta com tentativas restantes é processada novamente após o atraso de espera; uma tarefa que esgotou as tentativas é colocada em espera, e seu fluxo de trabalho é marcado como falho. Workers --once e a alternativa WP-Cron não executam essa verificação.

Recupere tarefas obsoletas manualmente:

Shell
wp queuety recover

Modo de processamento em lote

Processa todas as tarefas pendentes e encerra. Útil para testes ou processamento pontual em lote:

Shell
wp queuety flush
wp queuety flush --queue=emails

Implantação em produção

Em produção, use um gerenciador de processos para manter os workers em execução. Estas são duas abordagens comuns.

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

Ative e inicie:

Shell
sudo systemctl enable queuety-worker
sudo systemctl start queuety-worker

Dicas de implantação

Execute workers separados para filas distintas quando precisar de maior isolamento. Use --workers=N quando a carga for limitada pela CPU e prefira workers supervisionados individualmente quando ela depender principalmente de E/S. Defina QUEUETY_WORKER_MAX_JOBS se quiser reinicializações periódicas para liberar memória e monitore a contagem de buried por meio de webhooks ou métricas.