WordPressin sisäinen ajastusjärjestelmä, eli WP-Cron, on tunnettu siitä, että se ei ole oikea järjestelmätason cron, vaan pyyntöihin sidottu simuloitu ajastin. Vähemmän tunnettu osa tätä järjestelmää on cron-lock-mekanismi, jonka tarkoitus on estää useita rinnakkaisia cron-suorituksia.
Ilman tätä lukitusta WordPress voisi käynnistää saman cron-tehtävän useita kertoja samanaikaisesti, mikä johtaisi duplikaattitoimintoihin, kilpajuoksutilanteisiin ja suorituskykyongelmiin.
Miten WP-Cron käynnistyy
WP-Cron käynnistyy yleensä:
-
kun käyttäjä avaa sivun
-
kun WordPress tarkistaa ajastetut tehtävät
-
ja huomaa, että jokin niistä on erääntynyt
Tällöin WordPress tekee taustapyynnön:
Tämä pyyntö suorittaa kaikki ajastetut tehtävät, jotka ovat erääntyneet.
Miksi cron-lock tarvitaan
Ilman lukitusta seuraava tilanne on mahdollinen:
-
Sivustolle tulee 50 samanaikaista pyyntöä.
-
Jokainen pyyntö tarkistaa cronin.
-
Kaikki huomaavat, että cron on ajettava.
-
50 cron-prosessia käynnistyy yhtä aikaa.
Seuraukset:
-
sama sähköposti lähetetään 50 kertaa
-
sama varmuuskopio ajetaan useasti
-
tietokantaan syntyy race condition
Cron-lock estää tämän.
Miten cron-lock toimii teknisesti
WordPress käyttää transienttia nimeltä:
Kun cron käynnistyy:
-
WordPress asettaa
doing_cron-transientin. -
Transient sisältää aikaleiman.
-
Muut pyynnöt näkevät lukituksen ja ohittavat cronin.
Jos transient on olemassa:
-
uusi cron-suoritus estetään
-
järjestelmä odottaa lukituksen vapautumista
Lukituksen aikakatkaisu
Cron-lock ei ole ikuinen. WordPress käyttää aikakatkaisua, yleensä noin:
Jos cron-prosessi:
-
kaatuu
-
jää jumiin
-
ei poista lukitusta
lukitus vanhenee automaattisesti.
Tämä estää tilanteen, jossa cron pysähtyy pysyvästi.
Yleiset ongelmat cron-lockin kanssa
1. Hidas cron-tehtävä
Jos cron-tehtävä kestää:
-
yli lukituksen aikarajan
voi tapahtua:
-
uusi cron käynnistyy kesken vanhan
-
sama tehtävä suoritetaan kahdesti
Tämä on yleistä:
-
varmuuskopioissa
-
massapostituksissa
-
suurissa synkronoinneissa
2. Välimuistiin tallennetut transientit
Joillakin hosteilla transientit tallennetaan:
-
object cacheen
-
Memcachediin
-
Redisiin
Jos cache ei synkronoidu oikein:
-
eri prosessit eivät näe samaa lukitusta
-
syntyy rinnakkaisia cron-suorituksia
3. Sivustot, joilla on vähän liikennettä
Koska WP-Cron tarvitsee pyyntöjä käynnistyäkseen:
-
cron ei ehkä käynnisty ajallaan
-
lukitus voi jäädä vanhaksi
-
tehtävät kasaantuvat
DISABLE_WP_CRON ja oikea cron
Monilla tuotantosivustoilla WP-Cron poistetaan käytöstä:
Tämän jälkeen käytetään oikeaa järjestelmäcronin ajamaa komentoa:
Tämä:
-
vähentää rinnakkaisia suorituksia
-
tekee cronista ennustettavamman
-
parantaa suorituskykyä
Cron-lock toimii silti, mutta ympäristö on vakaampi.
Race condition -tilanteet
Cron-lock ei ole täydellinen lukitusmekanismi. Se perustuu transienttiin, joka:
-
ei ole atominen kaikissa ympäristöissä
-
voi kadota välimuistista
-
voi vanhentua kesken suorituksen
Tämä tarkoittaa, että:
-
kaksi cron-prosessia voi silti käynnistyä
-
erityisesti korkean liikenteen sivustoilla
Siksi kriittisissä tehtävissä:
-
käytetään omaa lukituslogiikkaa
-
esimerkiksi tietokantapohjaisia lukkoja
Suorituskykyvaikutukset
Cron-lock itsessään on kevyt operaatio, mutta sen virheellinen toiminta voi:
-
moninkertaistaa cron-suoritukset
-
kasvattaa CPU-kuormaa
-
aiheuttaa tietokantakilpailuja
Erityisesti suurissa sivustoissa tämä voi näkyä:
-
piikkeinä kuormassa
-
hitaana backendinä
-
aikakatkaisuina
Yhteenveto
WordPressin cron-lock-mekanismi:
-
estää rinnakkaiset cron-suoritukset
-
perustuu
doing_cron-transienttiin -
käyttää aikakatkaisua lukituksen vapauttamiseen
Se toimii hyvin pienissä ja keskisuurissa sivustoissa, mutta:
-
pitkät cron-tehtävät
-
object cache -ympäristöt
-
korkea liikenne
voivat rikkoa lukituslogiikan.
Cron-lock on enemmän kohtelias sopimus kuin kova mutex-lukko. Se sanoo prosesseille: “odotetaan vuoroamme”, mutta ei lukitse ovea rautaketjulla. Ja kun liikenne kasvaa tai ympäristö muuttuu monimutkaisemmaksi, tuo kohteliaisuus ei aina riitä pitämään kaaosta poissa.
