De ce se blochează coșul pe WooCommerce la mii de produse
Action Scheduler, cron-urile WordPress și cozile de sincronizare: ce se rupe la volum și cum se repară, din experiența unui magazin cu 15.000 de SKU.
Simptomul e mereu același și e ușor de recunoscut: magazinul merge normal, apoi la o campanie sau la o sincronizare de stoc, adăugarea în coș începe să dureze zece secunde, iar unele comenzi rămân în „pending" fără plată. Nu e serverul prea mic. E o coadă care înghite tot procesorul.
Cine rulează, de fapt, sarcinile programate
WordPress nu are un planificator adevărat. Are wp-cron.php, care se declanșează la
vizitele pe site. Pe un magazin cu trafic mic asta înseamnă că sarcinile se execută rar; pe unul cu
trafic mare înseamnă că vizitatorii tăi plătesc, cu timpul lor de încărcare, execuția lor.
Peste asta, WooCommerce adaugă Action Scheduler — o coadă proprie, ținută în baza de date, în care intră sincronizările de stoc, e-mailurile, actualizările de preț și tot ce fac plugin-urile în fundal. La 15.000 de produse și o sincronizare zilnică de la furnizor, coada poate ajunge la zeci de mii de acțiuni. Fiecare vizită de pe site încearcă să o miște.
Ce se rupe, în ordinea în care se rupe
- Tabelele Action Scheduler cresc necontrolat, fiindcă acțiunile executate nu se șterg implicit.
- Interogările pe aceste tabele devin lente, iar fiecare cerere de pagină așteaptă după ele.
- Coșul și finalizarea comenzii, care nu pot fi puse în cache, sunt primele care se simt.
- Procesele PHP se acumulează, serverul atinge limita de procese, iar restul cererilor stau la coadă.
Reparația, în patru pași
1. Oprește cron-ul declanșat de vizitatori
În wp-config.php adaugi define('DISABLE_WP_CRON', true); și pui un cron real
de sistem care apelează wp-cron.php la fiecare minut. Din acel moment, sarcinile nu mai
sunt plătite de vizitatori, iar execuția devine previzibilă.
2. Curăță coada și ține-o curată
Verifică numărul de acțiuni terminate din Action Scheduler. Dacă sunt zeci de mii, șterge-le și scurtează perioada de retenție. O coadă sănătoasă are sub câteva mii de rânduri în orice moment.
3. Fă sincronizarea în loturi, nu dintr-o dată
Un import care atinge 15.000 de produse într-o singură execuție va cădea la limita de timp și va reîncepe, uneori la nesfârșit. Se sparge în loturi de câteva sute, cu pauză între ele, și se rulează în fereastra cu trafic minim. Iar dacă furnizorul îți dă doar diferențele, cu atât mai bine: nu ai de ce să rescrii produse care nu s-au schimbat.
4. Nu pune coșul în cache, dar pune restul
Paginile de categorie și de produs se pot servi din cache agresiv. Coșul, finalizarea comenzii și contul nu — și trebuie excluse explicit, altfel apar erorile clasice cu produse care „dispar" din coș. Un strat de obiect-cache, de tip Redis, scade dramatic numărul de interogări repetate.
Cum știi că ai rezolvat
Măsoară trei lucruri, înainte și după: timpul de răspuns la adăugarea în coș, numărul de acțiuni în așteptare în coadă, și numărul de procese PHP active la vârf. Dacă primul scade sub o secundă, al doilea sub o mie și al treilea nu mai atinge limita, ai terminat. Dacă nu, problema e în altă parte — și atunci merită un test de încărcare, care îți arată exact ce cedează primul.