Sådan kører du baggrundsjobs i en webapp: Køer, planlæggere og cron
For at køre baggrundsjobs i en webapp skal du først dele arbejdet i to slags. Udløste jobs (send en velkomstmail, behandl en upload) kan gemmes i en jobkø, ofte en tabel i din database, og håndteres af en worker med genforsøg. Planlagte jobs (en nattlig rapport, påmindelser hvert 15. minut) kræver noget, der affyres efter et tidsskema: en hosts cron-funktion eller en ekstern planlægger, der kalder et beskyttet endpoint i din app. Gør altid jobs sikre at køre to gange, registrér fejl, og stol aldrig på en timer inde i en server, der kan gå i dvale eller genstarte.
Denne guide forklarer mulighederne, hvornår hver passer, og hvordan du opsætter dem med en AI-appbygger, også på hosts, der skalerer til nul.
Hvad der tæller som et baggrundsjob
Alt, der er langsomt, upålideligt eller ikke nødvendigt for brugerens umiddelbare svar:
- Afsendelse af e-mails, notifikationer og kvitteringer
- Ændring af størrelse på billeder, transkodning af video, generering af PDF'er
- Kald til langsomme tredjepartstjenester, herunder AI-modeller til lange opgaver
- Import eller synkronisering af data fra et andet system
- Nattlig oprydning, rapporter og påmindelser
Hvis du gør dette inde i anmodningen, bliver sider langsomme og skrøbelige: hvis e-mailudbyderen er nede, fejler brugerens tilmelding. Ved at flytte det til baggrunden får brugeren et øjeblikkeligt svar, og jobbet kan prøves igen.
Mulighederne
| Mulighed | Sådan virker den | Fordele | Ulemper |
|---|---|---|---|
| Fire-and-forget i samme proces | Svar, og fortsæt derefter arbejdet i serveren | Ingen opsætning | Tabes, hvis serveren stopper; ingen genforsøg |
Timer i processen (setInterval, setTimeout) | En timer i den kørende server | Trivielt | Kører ikke, mens den sover; dubletter ved flere kopier |
| Databasebaseret kø | Jobs gemmes som rækker; en worker tager og kører dem | Bruger den database, du har; holdbar; nem at inspicere | Du bygger genforsøg og låsning; kræver noget, der kører workeren |
| Dedikeret kø (Redis-baseret eller administreret) | En køtjeneste plus workers | Modne funktioner til genforsøg og planlægning | En ekstra tjeneste at køre og betale for |
| Hostet job- eller workflow-tjeneste | En tredjepart kalder dine endpoints med genforsøg og tidsplaner | Planlægning og genforsøg håndteret for dig | Leverandørafhængighed; en konto og nøgle mere |
| Ekstern planlægger, der kalder et endpoint | En timer et andet sted sender en HTTP-anmodning efter tidsplan | Virker på enhver host, også scale-to-zero | Minimumsintervaller og forsinkelser; beskyt endpointet |
| Hostens indbyggede cron | Platformen kører en kommando efter tidsplan | Enkel, hvor den findes | Ikke alle hosts tilbyder den |
Der findes ikke ét rigtigt svar. En lille app har ofte kun brug for en databasekø plus en ekstern planlægger.
Hvorfor hosts, der skalerer til nul, ændrer billedet
Mange moderne hosts sætter din app i dvale, når ingen bruger den, og vækker den ved næste anmodning. Det sparer penge, men en sovende server kører ingen kode: timere affyres ikke, og workers spørger ikke efter arbejde. På disse hosts skal planlagt arbejde starte med en indkommende anmodning, og den letteste kilde til den anmodning er en ekstern planlægger. Hvert kald vækker appen (og ofte dens database), så et kald hvert minut koster mere end et hvert 15. minut. Vælg den langsomste tidsplan, der opfylder behovet.
Mønster 1: en databasejobkø
Til udløste jobs:
- Opret en tabel
jobs: type, payload (JSON), status (pending,running,done,failed), attempts, run_after, last_error, tidsstempler. - Når noget sker, indsæt en jobrække i samme transaktion som den ændring, der forårsagede det, så de lykkes eller fejler sammen.
- En worker henter forfaldne jobs, markerer dem
running, udfører arbejdet og markerer demdone. - Ved fejl øger du
attempts, sætterrun_aftersenere (for eksempel 1, 5 og derefter 30 minutter) og gemmer fejlen. Efter et maksimum markeres detfailed, og en person får besked.
Hvis flere workers kan køre på én gang, skal jobs tages sikkert. På Postgres lader SELECT ... FOR UPDATE SKIP LOCKED hver worker tage forskellige rækker uden at kollidere.
Hvad kører workeren? På en server, der altid er tændt, en løkke i en separat proces. På en host, der skalerer til nul, kan endpointet med planlægningen i Mønster 2 behandle en batch af forfaldne jobs ved hvert kald.
Mønster 2: en ekstern planlægger, der kalder din app
Til planlagte jobs:
- Tilføj et endpoint som
POST /api/cron/send-reminders. - Beskyt det: kræv en hemmelig token i en header, gemt som en hemmelighed begge steder, og afvis alt andet.
- Gør det idempotent: at køre det to gange inden for samme minut må ikke sende to påmindelser. Registrér, hvad der er sendt.
- Hold hvert kald kort: behandl en batch (for eksempel 100 elementer), og lad næste kald tage resten.
- Peg en planlægger på det.
Valg af planlægger:
- GitHub Actions planlagte workflows. Gratis inden for GitHubs brugsgrænser. Pr. september 2026 siger GitHubs dokumentation, at det korteste interval er én gang hvert 5. minut, at kørsler kan forsinkes på travle tidspunkter (især ved timeskifte), at planlægning bruger UTC som standard, og at planlagte workflows i et offentligt repository deaktiveres efter 60 dage uden aktivitet i repositoryet.
- Hostede cron-tjenester. Mange tjenester findes, hvis eneste opgave er at kalde en URL efter en tidsplan. Tjek pålidelighed, mindste interval og advarsler, før du stoler på en.
- Din cloud-udbyders planlægger. Hvis du allerede bruger en stor cloud-udbyder, har den en administreret planlægger, der kan kalde et HTTPS-endpoint.
- En hostet job- eller workflow-tjeneste. Disse kombinerer planlægning, køer og genforsøg og kalder dine endpoints for hvert trin. Sammenlign priser og grænser på hver leverandørs side.
Mønster 3: lad udbyderen klare det
Somme gange er det bedste baggrundsjob slet ingen:
- Betalinger. Stripe prøver fejlede abonnementsbetalinger igen og sender webhooks; du reagerer i stedet for at polle. Se hvad en webhook er.
- E-mail. Udbydere køer og genforsøger levering, når du har afleveret beskeden.
- Masse-AI-arbejde. OpenAI og Anthropic tilbyder batch-API'er til ikke-hastende anmodninger, som du sender og henter senere.
Prompts til din AI-builder
Til en kø:
Tilføj en baggrundsjobkø med en jobs-tabel i vores database (type, payload JSON, status, attempts, run_after, last_error). Når en bruger tilmelder sig, indsæt et send_welcome_email-job i samme transaktion i stedet for at sende inline. Tilføj en funktion processJobs(limit), der tager forfaldne jobs med SELECT ... FOR UPDATE SKIP LOCKED, kører dem og prøver fejl igen efter 1, 5 og 30 minutter, og markerer dem som failed efter 4 forsøg.
Til en planlagt udløser:
Tilføj POST /api/cron/tick, beskyttet af et bearer-token fra hemmeligheden CRON_SECRET; afvis enhver anmodning uden det. Hvert kald kører processJobs(100) og sender bookingpåmindelser, der forfalder inden for de næste 24 timer, og som ikke er sendt endnu, og registrerer de sendte påmindelser, så intet sendes to gange. Returnér et JSON-resumé af, hvad der kørte. Skriv derefter en GitHub Actions-workflow, der kalder dette endpoint hvert 15. minut og læser URL'en og tokenet fra repository-hemmeligheder.
Almindelige fejl
- At stole på
setInterval. Den stopper stille og roligt, når serveren sover eller genstarter, og dobbeltkører, når to kopier kører. - Et ubeskyttet cron-endpoint. Alle, der finder det, kan udløse dine jobs eller din e-mailregning.
- Jobs, der ikke er idempotente. Genforsøg og dobbelte planlæggerkald vil ske. Design til det.
- Ingen synlighed ved fejl. Et job, der fejler stille i en uge, er værre end et, der fejler højlydt. Log fejl, og advar ved gentagne fejl.
- Lange kørsler i en enkelt anmodning. Anmodninger timer ud. Behandl i batches.
- At planlægge for ofte. Hvert kald på en host, der skalerer til nul, vækker og fakturerer appen. Tilpas intervallet til det reelle behov.
- Tidszoner. "Kl. 9" betyder forskellige ting for din planlægger (ofte UTC) og dine brugere. Gem tidspunkter i UTC, og konverter pr. bruger.
- Hemmeligheder i workflow-filen. Gem tokens i planlæggerens hemmelighedslager. Se sådan holder du API-nøgler sikre.
Tjekliste
- Langsomt arbejde er flyttet ud af brugeranmodninger
- Jobs gemmes holdbart, ikke kun i hukommelsen
- Genforsøg med stigende forsinkelser og et maksimum
- Hvert job er sikkert at køre to gange
- Planlagt endpoint beskyttet af en hemmelig token
- Hver kørsel behandler en afgrænset batch
- Fejlede jobs er synlige, med advarsler
- Planlægningsinterval valgt med hensyn til hostingomkostninger
- Tidspunkter gemt i UTC
Baggrundsjobs i Mythex
Mythex' dokumentation beskriver ikke planlagte eller cron-jobs, og publicerede apps og deres databaser går i dvale, når de er inaktive, og vågner ved næste anmodning (se Hostinggrænser). Stol derfor ikke på timere inde i din app. Den tilgang, der virker, er den ovenfor: bed agenten om en jobs-tabel og et token-beskyttet endpoint, og peg derefter en ekstern planlægger på din publicerede URL. Gem tokenet som en projekthemmelighed, og husk, at hver opvågning bruger kreditter for den tid, appen og databasen er vågen, så vælg et fornuftigt interval. Hvis din app har brug for en API-backend til dette, er REST API-backend-opskriften et godt udgangspunkt, og sådan bygger du en REST API dækker design af endpoints. Hvis always-on workers eller bots er kernen i dit produkt, passer en host, der er bygget til vedvarende processer, måske bedre.
Spørgsmål
Hvad er et baggrundsjob?
Et baggrundsjob er arbejde, din app udfører uden for den anmodning, en bruger venter på, for eksempel at sende e-mails, ændre størrelse på billeder, generere rapporter eller synkronisere data. Brugeren får et hurtigt svar, mens jobbet kører separat og kan prøves igen, hvis det fejler.
Hvordan kører jeg en planlagt opgave, hvis min host ikke har cron?
Tilføj et beskyttet endpoint, der udfører arbejdet, og lad derefter en ekstern planlægger kalde det efter en tidsplan. Muligheder omfatter en planlagt GitHub Actions-workflow, en hostet cron-tjeneste eller din cloud-udbyders planlægger. Beskyt endpointet med en hemmelig token.
Kan jeg bruge setInterval eller setTimeout til planlagte jobs?
Kun til små, uvigtige opgaver på en server, der altid kører. Hvis serveren genstarter, skalerer til nul eller kører flere kopier, går timere tabt eller kører mere end én gang. Gem planlagt arbejde i en database, eller brug en planlægger.
Understøtter Mythex cron-jobs?
Mythex' dokumentation beskriver ikke planlagte eller cron-jobs, og publicerede apps går i dvale, når de er inaktive. Den pålidelige tilgang er en ekstern planlægger, der kalder et beskyttet endpoint i din app, hvilket vækker appen og kører arbejdet.