Vadovai

Kaip vykdyti fonines užduotis žiniatinklio programėlėje: eilės, planuotojai ir cron

Norėdami vykdyti fonines užduotis žiniatinklio programėlėje, pirmiausia padalinkite darbą į dvi rūšis. Paleidžiamos užduotys (išsiųsti sveikinimo laišką, apdoroti įkėlimą) gali būti įrašytos į užduočių eilę, dažnai duomenų bazės lentelę, ir apdorotos darbuotojo su pakartojimais. Planuotos užduotys (naktinė ataskaita, priminimai kas 15 minučių) reikalauja kažko, kas paleidžiama pagal tvarkaraštį: hostingo cron funkcijos arba išorinio planuotojo, kuris kviečia apsaugotą galinį tašką jūsų programėlėje. Visada darykite užduotis saugias paleisti du kartus, fiksuokite klaidas ir niekada nesiremkite laikmačiu serveryje, kuris gali užmigti ar paleistis iš naujo.

Šis vadovas paaiškina galimybes, kada kiekviena tinka ir kaip jas nustatyti su DI programėlių kūrėju, įskaitant hostus, mažinančius iki nulio.

Kas laikoma fonine užduotimi

Viskas, kas lėta, nepatikima ar nereikalinga tiesioginiam naudotojo atsakymui:

  • El. laiškų, pranešimų ir kvitų siuntimas
  • Nuotraukų keitimas dydžiu, vaizdo konvertavimas, PDF generavimas
  • Lėtų trečiųjų šalių API kvietimai, įskaitant DI modelius ilgoms užduotims
  • Duomenų importavimas ar sinchronizavimas iš kitos sistemos
  • Naktinis valymas, ataskaitos ir priminimai

Jei tai daroma užklausos viduje, puslapiai lėtėja ir tampa trapūs: jei el. pašto teikėjas neveikia, naudotojo registracija nepavyksta. Perkėlus į foną naudotojas gauna momentinį atsakymą, o užduotį galima pakartoti.

Pasirinkimai

PasirinkimasKaip veikiaPrivalumaiTrūkumai
Paleidimas ir pamiršimas tame pačiame proceseAtsakote, tada tęsiate darbą serveryjeJokio nustatymoPrarandama, jei serveris sustoja; nėra pakartojimų
Procese veikiantis laikmatis (setInterval, setTimeout)Laikmatis veikiančiame serveryjeLabai paprastaNeveikia, kol snaudžia; dubliuojasi, jei kopijų kelios
Duomenų bazės grįsta eilėUžduotys įrašomos kaip eilutės; darbuotojas jas paima ir vykdoNaudoja turimą duomenų bazę; patvarumas; lengva tikrintiPakartojimus ir užrakinimą kuriate patys; reikia, kas paleistų darbuotoją
Atskira eilė (Redis pagrindu ar valdoma)Eilės paslauga ir darbuotojaiBrandūs pakartojimo ir planavimo funkcijosDar viena paslauga, kurią reikia valdyti ir mokėti už ją
Hostinguojama darbų ar darbo srautų paslaugaTrečioji šalis kviečia jūsų galinius taškus su pakartojimais ir tvarkaraščiaisPlanavimą ir pakartojimus tvarko jiePriklausomybė nuo tiekėjo; dar viena paskyra ir raktas
Išorinis planuotojas, kviečiantis galinį taškąKitur veikiantis laikmatis siunčia HTTP užklausą pagal tvarkaraštįVeikia bet kuriame hoste, įskaitant mažinamus iki nulioMinimalūs intervalai ir vėlavimai; galinį tašką reikia apsaugoti
Hosto integruotas cronPlatforma paleidžia komandą pagal tvarkaraštįPaprasta, kur yraNe kiekvienas hostas tai siūlo

Vienintelio teisingo atsakymo nėra. Mažai programėlei dažnai pakanka tik duomenų bazės eilės ir išorinio planuotojo.

Kodėl hostai, mažinantys iki nulio, keičia vaizdą

Daugelis šiuolaikinių hostų užmigdo jūsų programėlę, kai niekas jos nenaudoja, ir pažadina kitos užklausos metu. Tai sutaupo pinigų, bet snaudžiantis serveris nevykdo jokio kodo: laikmačiai neveikia, darbuotojai neklausia eilės. Tokiuose hostuose suplanuotas darbas turi prasidėti nuo gaunamos užklausos, o lengviausias tokios užklausos šaltinis – išorinis planuotojas. Kiekvienas iškvietimas pažadina programėlę (ir dažnai jos duomenų bazę), todėl kvietimas kas minutę kainuoja daugiau nei kas 15 minučių. Pasirinkite lėčiausią tvarkaraštį, kuris tenkina poreikį.

Šablonas 1: duomenų bazės užduočių eilė

Paleidžiamoms užduotims:

  1. Sukurkite jobs lentelę: tipas, duomenys (JSON), būsena (pending, running, done, failed), bandymai, run_after, last_error, laiko žymos.
  2. Kai kas nors įvyksta, įrašykite užduoties eilutę toje pačioje transakcijoje kaip ir pakeitimas, kuris ją sukėlė, kad jos pavyktų arba nepavyktų kartu.
  3. Darbuotojas paima paruoštas užduotis, pažymi jas running, atlieka darbą ir pažymi done.
  4. Nepavykus padidinkite attempts, nustatykite vėlesnį run_after (pavyzdžiui, po 1, 5, tada 30 minučių) ir įrašykite klaidą. Pasiekus maksimalų skaičių, pažymėkite failed ir įspėkite ką nors.

Jei galbūt vienu metu veiks daugiau nei vienas darbuotojas, užduotys turi būti paimamos saugiai. Postgres duomenų bazėje SELECT ... FOR UPDATE SKIP LOCKED leidžia kiekvienam darbuotojui paimti skirtingas eilutes be susidūrimų.

Kas paleidžia darbuotoją? Visada įjungtame serveryje – ciklas atskirame procese. Hoste, mažinančiame iki nulio, planuoto galinio taško iš 2 šablono kiekvienas iškvietimas gali apdoroti paruoštų užduočių partiją.

Šablonas 2: išorinis planuotojas, kviečiantis jūsų programėlę

Planuotoms užduotims:

  1. Pridėkite galinį tašką, pavyzdžiui POST /api/cron/send-reminders.
  2. Apsaugokite jį: reikalaukite paslapties žetono antraštėje, saugomo kaip paslaptis abiejose pusėse, ir atmetkite viską kita.
  3. Padarykite jį idempotentišku: paleidus du kartus per tą pačią minutę, priminimai neturi būti išsiųsti du kartus. Įrašykite, kas išsiųsta.
  4. Laikykite kiekvieną iškvietimą trumpą: apdorokite partiją (tarkime, 100 elementų) ir leiskite kitam iškvietimui paimti likusius.
  5. Nukreipkite planuotoją į jį.

Planuotojo pasirinkimai:

  • GitHub Actions suplanuoti darbo srautai. Nemokami GitHub naudojimo limitų ribose. Pagal GitHub dokumentaciją 2026 m. rugsėjį trumpiausias intervalas yra kartą per 5 minutes, paleidimai gali vėluoti įprastu metu (ypač kiekvienos valandos pradžioje), tvarkaraščiai pagal numatytuosius nustatymus naudoja UTC, o suplanuoti darbo srautai viešoje saugykloje išjungiami po 60 dienų be saugyklos veiklos.
  • Hostinguojamos cron paslaugos. Yra daug paslaugų, kurių vienintelis darbas – iškviesti URL pagal tvarkaraštį. Prieš jomis pasitikėdami patikrinkite patikimumą, minimalų intervalą ir įspėjimus.
  • Jūsų debesijos teikėjo planuotojas. Jei jau naudojate didelį debesijos teikėją, jis turės valdomą planuotoją, galintį iškviesti HTTPS galinį tašką.
  • Hostinguojama darbų ar darbo srautų paslauga. Jos sujungia planavimą, eiles ir pakartojimus bei kiekvienam žingsniui kviečia jūsų galinius taškus. Kainas ir limitus palyginkite kiekvieno tiekėjo svetainėje.

Šablonas 3: leiskite teikėjui tai atlikti

Kartais geriausia fono užduotis – jokia:

  • Mokėjimai. Stripe pakartoja nepavykusius prenumeratos mokėjimus ir siunčia webhook'us; jūs reaguojate, o ne klausinėjate. Žr. kas yra webhook.
  • El. paštas. Teikėjai eilina ir pakartoja pristatymą, kai jiems perduodate laišką.
  • Masinis DI darbas. OpenAI ir Anthropic siūlo paketinius API neskubiems užklausimams, kuriuos pateikiate ir surenkate vėliau.

Užklausos jūsų DI kūrėjui

Eilei:

Pridėk fono užduočių eilę, naudodamas jobs lentelę mūsų duomenų bazėje (tipas, JSON duomenys, būsena, bandymai, run_after, last_error). Kai naudotojas registruojasi, įrašyk send_welcome_email užduotį į tą pačią transakciją vietoj siuntimo tiesiogiai. Pridėk funkciją processJobs(limit), kuri paima paruoštas užduotis naudodama SELECT ... FOR UPDATE SKIP LOCKED, jas vykdo ir pakartoja nesėkmes po 1, 5 ir 30 minučių, pažymėdama jas kaip nepavykusias po 4 bandymų.

Planuotam paleidimui:

Pridėk POST /api/cron/tick, apsaugotą bearer žetonu iš paslapties CRON_SECRET; atmesk bet kokią užklausą be jo. Kiekvienas iškvietimas vykdo processJobs(100) ir siunčia rezervacijos priminimus, kurie turi įvykti per artimiausias 24 valandas ir dar nebuvo išsiųsti; išsiųstus priminimus įrašyk, kad nieko nesiųstume dukart. Grąžink JSON santrauką, ką įvykdė. Tada parašyk GitHub Actions darbo srautą, kuris kviečia šį galinį tašką kas 15 minučių, skaitydamas URL ir žetoną iš saugyklos paslapčių.

Dažnos klaidos

  • Pasikliovimas setInterval. Jis tyliai sustoja, kai serveris snaudžia ar paleidžiamas iš naujo, ir dubliuojasi, kai veikia kelios kopijos.
  • Neapsaugotas cron galinis taškas. Bet kas, kas jį suras, galės paleisti jūsų užduotis ar padidinti jūsų el. pašto sąskaitą.
  • Užduotys, kurios nėra idempotentiškos. Pakartojimai ir dvigubi planuotojo iškvietimai įvyks. Projektuokite jiems.
  • Nėra matomumo klaidoms. Užduotis, kuri savaitę tyliai nepavyksta, yra blogesnė nei ta, kuri garsiai praneša. Fiksuokite klaidas ir įspėkite apie pasikartojančias nesėkmes.
  • Ilgi paleidimai vienoje užklausoje. Užklausos baigiasi per laiką. Apdorokite partijomis.
  • Per dažnas planavimas. Kiekvienas iškvietimas hoste, mažinančiame iki nulio, pažadina ir apmokestina programėlę. Suderinkite intervalą su tikru poreikiu.
  • Laiko juostos. „9 val. ryto“ reiškia skirtingus dalykus jūsų planuotojui (dažnai UTC) ir naudotojams. Laikus saugokite UTC ir konvertuokite kiekvienam naudotojui.
  • Paslaptys darbo srauto faile. Laikykite žetonus planuotojo paslapčių saugykloje. Žr. kaip saugoti API raktus.

Kontrolinis sąrašas

  • Lėtas darbas perkeltas iš naudotojo užklausų
  • Užduotys saugomos patvariai, ne tik atmintyje
  • Pakartojimai su didėjančiais vėlavimais ir maksimumu
  • Kiekviena užduotis saugi paleisti du kartus
  • Planuotas galinis taškas apsaugotas paslapties žetonu
  • Kiekvienas paleidimas apdoroja ribotą partiją
  • Nepavykusios užduotys matomos, su įspėjimais
  • Tvarkaraščio intervalas parinktas atsižvelgiant į hostingo išlaidas
  • Laikai saugomi UTC

Fono užduotys Mythex

Mythex dokumentacijoje planuotos ar cron užduotys neaprašytos, o paskelbtos programėlės ir jų duomenų bazės snaudžia, kai neaktyvios, ir pabunda kitos užklausos metu (žr. Hostingo limitai). Todėl nesiremkite laikmačiais savo programėlės viduje. Veikia tas metodas, kurį aprašėme aukščiau: paprašykite agento sukurti užduočių lentelę ir galinį tašką, apsaugotą žetonu, tada nukreipkite išorinį planuotoją į savo paskelbtą URL. Žetoną saugokite kaip projekto paslaptį ir atsiminkite, kad kiekvienas pabudimas kainuoja kreditus už laiką, kurį programėlė ir duomenų bazė buvo budrios, todėl pasirinkite protingą intervalą. Jei jūsų programėlei tam reikia API serverio, REST API backend receptas yra pradžios taškas, o kaip sukurti REST API aprašo galinių taškų kūrimą. Jei jūsų produkto esmė – nuolat veikiantys darbuotojai ar botai, geriau gali tikti hostas, skirtas ilgai veikiantiems procesams.

Klausimai

Kas yra fonas užduotis?

Fono užduotis – tai darbas, kurį programėlė atlieka už naudotojo laukiamos užklausos ribų, pavyzdžiui siunčia el. laiškus, keičia nuotraukų dydį, generuoja ataskaitas ar sinchronizuoja duomenis. Naudotojas gauna greitą atsakymą, o užduotis vykdoma atskirai ir gali būti pakartota, jei nepavyko.

Kaip paleisti planuotą užduotį, jei mano hostingas neturi cron?

Pridėkite apsaugotą galinį tašką, kuris atlieka darbą, ir leiskite išoriniam planuotojui jį iškviesti pagal tvarkaraštį. Pasirinkimai: suplanuotas GitHub Actions darbo srautas, hostinguojama cron paslauga arba debesijos teikėjo planuotojas. Apsaugokite galinį tašką slaptu žetonu.

Ar galiu naudoti setInterval ar setTimeout planuotoms užduotims?

Tik mažoms, nesvarbioms užduotims serveryje, kuris visada veikia. Jei serveris paleidžiamas iš naujo, mažinamas iki nulio ar veikia keliomis kopijomis, laikmačiai prarandami arba veikia daugiau nei vieną kartą. Saugokite suplanuotus darbus duomenų bazėje arba naudokite planuotoją.

Ar Mythex palaiko cron užduotis?

Mythex dokumentacijoje planuotos ar cron užduotys neaprašytos, o paskelbtos programėlės snaudžia, kai neaktyvios. Patikimas būdas – išorinis planuotojas, kviečiantis apsaugotą galinį tašką jūsų programėlėje; jis pažadina programėlę ir atlieka darbą.

Mythex · Pricing · Kurkite bet ką su dirbtiniu intelektu · Svetainių ir programėlių šablonai · Mythex palyginimas · Programėlių kūrimo su dirbtiniu intelektu žodynėlis · Nemokami programėlių kūrimo su dirbtiniu intelektu įrankiai · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)