Procesy robocze
Procesy robocze to długotrwale działające procesy, które odpytują bazę danych o oczekujące zadania, wykonują je i posuwają przepływy pracy naprzód. Polecenie wp queuety work działa wewnątrz WP-CLI, a kolejka jest pobierana bezpośrednio z MySQL za pośrednictwem najlepszego dostępnego sterownika DB Queuety.
Wtyczka instaluje też domyślny mechanizm awaryjny WordPress cron uruchamiany raz na minutę, przeznaczony dla środowisk bez dostępu do powłoki. Ta strona opisuje dedykowane procesy robocze WP-CLI, zalecany tryb wdrożenia zapewniający większą przepustowość.
Uruchamianie procesu roboczego
wp queuety work
Uruchamia to pojedynczy proces roboczy dla kolejki default. Działa on w pętli: pobiera zadanie, wykonuje je i powtarza cykl. Gdy kolejka jest pusta, czeka QUEUETY_WORKER_SLEEP sekund (domyślnie: 1), a następnie ponownie odpytuje kolejkę.
Opcje
| Opcja | Opis |
|---|---|
--queue=<queue> |
Queue(s) do przetworzenia; nazwy oddzielone przecinkami ustalają kolejność priorytetów (domyślnie: default) |
--once |
Przetwórz najwyżej jedno zadanie i zakończ działanie |
--workers=<n> |
Rozgałęź procesy robocze na N procesów (wymaga rozszerzeń pcntl i posix) |
--min-workers=<n> |
Minimalna liczba procesów roboczych w puli adaptacyjnej. Wymaga --max-workers |
--max-workers=<n> |
Maksymalna liczba procesów roboczych w puli adaptacyjnej |
# 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
Priorytety wielu kolejek
Pojedynczy proces roboczy może przetwarzać wiele kolejek w kolejności priorytetów. Przekaż do --queue rozdzieloną przecinkami listę nazw kolejek:
wp queuety work --queue=critical,default,low
Proces roboczy próbuje pobrać zadanie z każdej kolejki w podanej kolejności. Najpierw sprawdza critical. Jeśli critical zawiera zadanie, przetwarza je. Jeśli critical jest pusta, przechodzi do default, a następnie do low. Oznacza to, że kolejki o wyższym priorytecie są zawsze opróżniane przed tymi o niższym priorytecie.
Jak działa kolejność priorytetów
W każdej iteracji proces roboczy próbuje pobrać zadanie z pierwszej kolejki na liście. Jeśli kolejka jest pusta lub wstrzymana, przechodzi do następnej i kontynuuje, aż znajdzie zadanie albo sprawdzi całą listę. Jeśli nigdzie nie znajdzie zadania, czeka i ponawia próbę. To ścisły model priorytetów, co oznacza, że stały napływ zadań critical zagłodzi kolejki default i low. Jeśli kolejki o niższym priorytecie mają mieć gwarantowaną przepustowość, użyj dedykowanych procesów roboczych.
Korzystanie z wielu kolejek w PHP
Metody Worker::run() i Worker::flush() przyjmują ciąg znaków lub tablicę:
// 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' );
Strategie wdrażania
Dedykowane procesy robocze dla każdej kolejki zapewniają pełną kontrolę nad współbieżnością i izolacją. Każda kolejka ma własny proces roboczy process(es), więc inne kolejki nie mogą go zagłodzić:
[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
Kolejność priorytetów w pojedynczym procesie roboczym jest łatwiejsza w zarządzaniu i sprawdza się, gdy kolejki o niższym priorytecie mogą tolerować opóźnienia:
[program:queuety-worker]
command=wp queuety work --queue=critical,default,low
numprocs=2
Możesz też połączyć oba podejścia: użyć dedykowanych procesów roboczych dla critical, aby zagwarantować przepustowość, a dla pozostałych kolejek procesu roboczego z kolejnością priorytetów:
[program:queuety-critical]
command=wp queuety work --queue=critical
numprocs=2
[program:queuety-fallback]
command=wp queuety work --queue=default,low
numprocs=2
Przydzielanie zasobów z ich uwzględnieniem
Procesy robocze robią więcej niż tylko pobierają kolejny oczekujący wiersz. Przed rozpoczęciem pobranego zadania Queuety może zastosować wstępne kontrole dopuszczenia na podstawie grupy współbieżności zadania i niedawnego profilu wykonania tego obsługującego je kodu.
Więcej informacji o całym modelu i jego powiązaniu z metadanymi zadań oraz limitami przepływów pracy znajdziesz w sekcji Zarządzanie zasobami.
Grupa współbieżności wyznacza wspólny limit dla kilku programów obsługi lub klas zadań. Jeśli kilka kosztownych dostawców przypiszesz do tej samej grupy i limitu, proces roboczy zwolni nowo pobrane zadanie zamiast je uruchamiać, gdy grupa osiągnie limit. Dzięki temu niezależne kolejki nie przeciążą jednego systemu podrzędnego tylko dlatego, że kilka procesów roboczych jest bezczynnych.
Niedawne dzienniki wykonania służą też do tworzenia prostego profilu dopuszczania. Gdy ta funkcja jest włączona, Queuety sprawdza niedawny średni czas trwania i szczytowe zużycie pamięci programu obsługi, który ma uruchomić. Jeśli bieżący proces roboczy zbliża się już do skonfigurowanego limitu pamięci, kolejka lub grupa dostawców osiągnęła już swój ważony budżet, bieżący kontener nie ma dość wolnej pamięci na podstawie zaobserwowanego profilu programu obsługi albo uruchomienie w stylu --once zbliża się do limitu czasu, Queuety odracza zadanie zamiast rozpoczynać pracę, która prawdopodobnie nie zakończy się poprawnie.
Zasady włączasz w definicji zadania, a nie w poleceniu procesu roboczego:
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,
];
}
}
Te same metadane można dołączyć do klas zadań możliwych do wysłania, używając właściwości publicznych, albo do pojedynczego wysłania za pomocą PendingJob::concurrency_group() i PendingJob::cost_units().
Profile dopuszczania po stronie procesu roboczego kontrolują następujące stałe:
| Stała | Opis |
|---|---|
QUEUETY_RESOURCE_ADMISSION |
Włączanie lub wyłączanie kontroli dopuszczania na podstawie profilu |
QUEUETY_RESOURCE_PROFILE_WINDOW_MINUTES |
Zakres czasu uwzględniany przy tworzeniu niedawnych profili programów obsługi |
QUEUETY_RESOURCE_PROFILE_TTL |
Czas TTL pamięci podręcznej niedawnych profili programów obsługi |
QUEUETY_RESOURCE_MEMORY_HEADROOM_MB |
Rezerwa pamięci przed dopuszczeniem kolejnego zadania |
QUEUETY_RESOURCE_SYSTEM_MEMORY_AWARENESS |
Włączanie lub wyłączanie przybliżonych kontroli pamięci kontenera lub hosta |
QUEUETY_RESOURCE_SYSTEM_MEMORY_HEADROOM_MB |
Rezerwa pamięci systemowej przed dopuszczeniem kolejnego zadania |
QUEUETY_RESOURCE_QUEUE_COST_BUDGETS |
Ważone budżety kosztów według nazwy kolejki |
QUEUETY_RESOURCE_GROUP_COST_BUDGETS |
Ważone budżety kosztów według concurrency_group |
QUEUETY_RESOURCE_TIME_HEADROOM_MS |
Rezerwa czasu dla jednorazowych uruchomień procesów roboczych |
Cykl życia procesu roboczego
Proces roboczy zatrzymuje się poprawnie po zakończeniu bieżącego zadania, gdy spełniony jest jeden z następujących warunków:
| Warunek | Konfiguracja |
|---|---|
| Maksymalna liczba przetworzonych zadań | QUEUETY_WORKER_MAX_JOBS (domyślnie: 1000) |
| Przekroczony limit pamięci | QUEUETY_WORKER_MAX_MEMORY (domyślnie: 128 MB) |
Po zatrzymaniu proces roboczy kończy działanie bez błędów. W środowisku produkcyjnym menedżer procesów uruchamia go ponownie automatycznie.
Obsługa sygnałów nie jest jeszcze poprawna (#4). Pojedynczy proces wp queuety work nie instaluje obsługi sygnałów, więc SIGTERM lub SIGINT (Ctrl+C) kończy go natychmiast, nawet w trakcie zadania. Zadanie pozostaje w stanie processing do czasu, aż odzyskiwanie nieaktualnych zadań zresetuje je po QUEUETY_STALE_TIMEOUT sekundach, dlatego programy obsługi powinny bezpiecznie znosić ponowne próby. Pula procesów roboczych przekazuje SIGTERM swoim procesom potomnym, ale te nie reagują na niego, więc pula działa dalej, dopóki nie zostaną zatrzymane z jednego z wymienionych powodów. Gdy trzeba zatrzymać pulę, ustaw w menedżerze procesów limit czasu zatrzymania, po którym wyśle SIGKILL.
Współbieżność wielu procesów roboczych
Flaga --workers=N rozgałęzia N procesów potomnych za pomocą pcntl_fork(). Każdy proces potomny nawiązuje własne połączenie z bazą danych i niezależnie przetwarza zadania. Proces nadrzędny monitoruje procesy potomne i uruchamia ponownie te, które ulegną awarii.
wp queuety work --queue=default --workers=4
Wymagania:
Rozszerzenia pcntl i posix PHP muszą być zainstalowane (bez pcntl polecenie kończy się błędem „pcntl extension is required for --workers=N.”). Każdy proces potomny używa własnego połączenia z bazą danych, więc ustawienie MySQL max_connections musi uwzględniać pulę. Pule adaptacyjne (--min-workers/--max-workers) mają te same wymagania.
Adaptacyjne pule procesów roboczych
Pule adaptacyjne utrzymują minimalną liczbę gotowych procesów roboczych, a następnie zwiększają ją i zmniejszają w skonfigurowanym zakresie:
wp queuety work --queue=providers --min-workers=2 --max-workers=6
Proces nadrzędny obserwuje liczbę zadań gotowych do pobrania w wybranych kolejkach i dostosowuje liczbę procesów potomnych do zaległości, nie przekraczając skonfigurowanego maksimum. Gdy w kolejce robi się spokojnie, pula czeka przez określony czas bezczynności przed zmniejszeniem rozmiaru, aby krótkie skoki obciążenia nie powodowały natychmiastowych zmian listy procesów.
Zwiększanie skali jest nadal ostrożne. Gdy Queuety może odczytać dane o pamięci kontenera lub hosta, nie dodaje kolejnych procesów potomnych, jeśli nie ma dość wolnej pamięci na pełny zestaw zasobów kolejnego procesu roboczego.
Pętlę skalowania po stronie procesu nadrzędnego kontrolują:
| Stała | Opis |
|---|---|
QUEUETY_WORKER_POOL_SCALE_INTERVAL |
Jak często proces nadrzędny uzgadnia rozmiar puli |
QUEUETY_WORKER_POOL_IDLE_GRACE |
Jak długo zaległości muszą pozostawać bez zmian, zanim pula zmniejszy rozmiar |
Odzyskiwanie nieaktualnych zadań
Jeśli proces roboczy ulegnie awarii podczas przetwarzania zadania, zadanie pozostaje w stanie processing. Długotrwale działający proces roboczy mniej więcej raz na minutę sprawdza, czy są zadania, które pozostają w stanie processing dłużej niż QUEUETY_STALE_TIMEOUT sekund. Nieaktualne zadanie, któremu pozostały próby, jest ponawiane po upływie czasu oczekiwania; zadanie, które wykorzystało wszystkie próby, trafia do archiwum, a jego przepływ pracy zostaje oznaczony jako nieudany. Procesy robocze --once i mechanizm awaryjny WP-Cron nie wykonują tego sprawdzenia.
Odzyskaj nieaktualne zadania ręcznie:
wp queuety recover
Tryb opróżniania
Przetwórz wszystkie oczekujące zadania i zakończ działanie. Przydatne do testowania lub jednorazowego przetwarzania wsadowego:
wp queuety flush
wp queuety flush --queue=emails
Wdrożenie produkcyjne
W środowisku produkcyjnym użyj menedżera procesów, aby procesy robocze działały bez przerwy. Oto dwa popularne sposoby.
Supervisord
[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
[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
Włącz i uruchom:
sudo systemctl enable queuety-worker
sudo systemctl start queuety-worker
Wskazówki dotyczące wdrażania
Uruchamiaj osobne procesy robocze dla poszczególnych kolejek, gdy potrzebujesz lepszej izolacji. Użyj --workers=N, gdy obciążenie ogranicza procesor, a przy obciążeniu związanym głównie z operacjami wejścia-wyjścia preferuj osobne nadzorowane procesy robocze. Ustaw QUEUETY_WORKER_MAX_JOBS, jeśli chcesz okresowo uruchamiać procesy ponownie, aby zwolnić pamięć, i obserwuj liczbę buried w webhookach lub metrykach.