- Vaša košarica je trenutno prazna
Opravila v ozadju Python aplikacije: cron, PM2 in kaj ne deluje
Pošiljanje e-pošte, izdelava poročil, uvoz podatkov, čiščenje starih zapisov: skoraj vsaka aplikacija ima opravila, ki se izvajajo v ozadju (ang. background tasks), brez čakanja uporabnika.
Na vašem računalniku je za to dovolj nit (ang. thread) ali asyncio.create_task. Na spletnem gostovanju pa to ne deluje tako, kot bi morda pričakovali. V tem prispevku boste izvedeli, zakaj, in katere rešitve delujejo.
Kazalo
- Zakaj nit v aplikaciji ne deluje?
- Izberite pravo rešitev
- Cron: opravila ob določenem času
- PM2: proces, ki teče ves čas
- Pogosta vprašanja
Zakaj nit v aplikaciji ne deluje?
Python aplikacija, ustvarjena v Setup Python App, ne teče ves čas:
- spletni strežnik jo zažene ob zahtevku in obdelavo razdeli med več delovnih procesov,
- med zahtevki so procesi zaustavljeni, zato se niti in naloge v ozadju ne izvajajo,
- po nekaj minutah brez obiska se aplikacija v celoti zaustavi, z njo pa tudi vse nedokončane naloge.
Še več: nit, ki jo koda zažene ob uvozu aplikacije, lahko povzroči, da se zahtevki zataknejo. Zato v datotekah, ki jih uvozi passenger_wsgi.py, ob uvozu ne zaganjajte niti, razporejevalnikov (npr. APScheduler) ali zank dogodkov.
Tudi FastAPI BackgroundTasks se izvedejo, vendar uporabnik na odgovor čaka, dokler se naloga ne konča.
Izberite pravo rešitev
| Potreba | Rešitev |
|---|---|
| Opravilo ob določenem času (poročilo, čiščenje, varnostna kopija) | cron |
| Kratko opravilo po zahtevku (do nekaj sekund) | izvedite ga kar v zahtevku |
| Daljša obdelava, ki jo sproži uporabnik | zapis v bazo + obdelava s cronom |
| Proces, ki mora teči ves čas | PM2, priporočeno na paketu Turbo (glejte spodaj) |
| Stalna obdelava podatkov, vrste opravil z veliko prometa | VPS strežnik |
Cron: opravila ob določenem času
Cron opravilo (ang. cron job) nastavite v cPanel → Cron Jobs ali v terminalu z ukazom crontab -e. Na spletnem gostovanju se posamezno opravilo lahko izvede največ enkrat na 30 minut.
Primer: vsako noč ob 3.15 zaženite skripto porocilo.py v virtualnem okolju aplikacije:
15 3 * * * export OPENBLAS_NUM_THREADS=1; cd $HOME/mojaapi && $HOME/virtualenv/mojaapi/3.11/bin/python porocilo.py >> $HOME/mojaapi/cron.log 2>&1
Pomembno je, da uporabite Python iz virtualnega okolja aplikacije, sicer skripta ne najde nameščenih paketov.
Vzorec: obdelava z zamikom
Ko uporabnik sproži daljšo obdelavo (npr. uvoz datoteke), aplikacija zapiše nalogo v bazo in takoj odgovori »naloga je v obdelavi«. Cron vsakih 30 minut zažene skripto, ki obdela vse čakajoče naloge in označi, da so končane.
*/30 * * * * cd $HOME/mojaapi && $HOME/virtualenv/mojaapi/3.11/bin/python obdelaj_naloge.py >> $HOME/mojaapi/naloge.log 2>&1
PM2: proces, ki teče ves čas
Če potrebujete proces, ki teče neprekinjeno (npr. uvicorn za WebSocket ali delavca, ki sproti obdeluje vrsto nalog), uporabite upravitelja procesov PM2. PM2 proces ob napaki samodejno znova zažene.
Namestitev:
export PATH=/opt/alt/alt-nodejs22/root/usr/bin:$PATH
mkdir -p ~/pm2 && cd ~/pm2
npm install pm2
Zagon Python skripte:
export PATH=/opt/alt/alt-nodejs22/root/usr/bin:$PATH
export PM2_HOME=~/pm2/.pm2
~/pm2/node_modules/.bin/pm2 start ~/mojaapi/delavec.py \
--name delavec \
--interpreter ~/virtualenv/mojaapi/3.11/bin/python \
--cwd ~/mojaapi
~/pm2/node_modules/.bin/pm2 save
Uporabni ukazi (z enakima vrsticama export kot zgoraj):
~/pm2/node_modules/.bin/pm2 list # seznam procesov
~/pm2/node_modules/.bin/pm2 logs delavec # dnevnik
~/pm2/node_modules/.bin/pm2 restart delavec
~/pm2/node_modules/.bin/pm2 delete delavec
Samodejni zagon po ponovnem zagonu strežnika
Ob vzdrževanju strežnika se procesi zaustavijo. Da jih PM2 znova zažene, pripravite skripto ~/pm2/zagon.sh:
#!/bin/bash
export PATH=/opt/alt/alt-nodejs22/root/usr/bin:$PATH
export PM2_HOME=$HOME/pm2/.pm2
export OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1
PM2=$HOME/pm2/node_modules/.bin/pm2
# če ne teče noben proces, obnovi shranjeno stanje (pm2 save)
$PM2 jlist | grep -q '"status":"online"' || $PM2 resurrect
in dodajte dve cron opravili:
@reboot /bin/bash $HOME/pm2/zagon.sh >/dev/null 2>&1
*/30 * * * * /bin/bash $HOME/pm2/zagon.sh >/dev/null 2>&1
Prvo opravilo procese zažene ob zagonu strežnika, drugo pa vsakih 30 minut preveri, ali tečejo, in jih po potrebi znova zažene. Ob vsaki spremembi procesov ne pozabite na pm2 save.
Skripto ustvarite v urejevalniku datotek v cPanel ali jo naložite kot datoteko (če jo vpisujete prek ukaza v narekovajih, se narekovaji v njej interpretirajo nepravilno). Skripta obnovi procese, ko ne teče noben od njih.
Na kaj morate paziti?
Pri izvajanju opravil v ozadju upoštevajte naslednje omejitve in priporočila:
- Proces, ki teče ves čas, neprestano porablja pomnilnik vašega paketa (pri paketu Zeleni je na voljo 1 GB) in šteje v omejitev števila procesov. Za stalno delujoče procese priporočamo Turbo gostovanje z več pomnilnika in procesorskih jeder.
- Delavec naj ne obremenjuje procesorja v zanki. Med preverjanji naj čaka (
time.sleep), naloge pa naj obdela, ko se pojavijo. - V skladu s pogoji uporabe spletno gostovanje ni namenjeno aplikacijam z neprekinjeno porabo sistemskih sredstev (obdelava in zbiranje podatkov, analitika). Za take aplikacije priporočamo VPS strežnik.
Pogosta vprašanja
Spoznajte odgovore na pogosta vprašanja o izvajanju opravil v ozadju.
Ali lahko uporabim Celery, RQ ali Redis?
Za Celery in RQ potrebujete posrednika (Redis ali RabbitMQ) in stalno delujoče delavce. Za manjše aplikacije je preprostejša in zanesljivejša rešitev vrsta nalog v bazi in cron. Za večje sisteme priporočamo VPS gostovanje.
Ali se uvicorn ali skripta, zagnana z nohup, zaustavi, ko zaprem SSH?
Ne, proces, zagnan z nohup ... &, teče naprej. Vendar ga ob napaki ali ponovnem zagonu strežnika nihče ne zažene znova, zato priporočamo PM2.
Kako vem, da cron deluje?
Preusmerite izpis v datoteko (>> cron.log 2>&1) ali v cPanel → Cron Jobs vpišite e-poštni naslov, na katerega dobite izpis vsakega izvajanja.
Če potrebujete pomoč pri nastavitvi opravil v ozadju, smo vam na voljo.
KOMENTIRAJTE OBJAVO
Vaš komentar je bil uspešno oddan
Komentar bo viden na strani, ko ga naši moderatorji potrdijo.