Naar de inhoud
maarten.
Alle stories

Synchrone verwerking of job queue: wanneer kies je wat?

Maarten Soetens 12 min lezen

Bij synchrone verwerking wacht een gebruiker op het resultaat terwijl de applicatie een taak uitvoert. Met een job queue kan de applicatie werk overdragen aan een achtergrondworker; dat verandert de responstijd, foutafhandeling en manier waarop je taakstatus bijhoudt. Lees welke afwegingen bepalen welk model bij een proces past.

Wat synchrone verwerking betekent voor een webverzoek

Bij synchrone verwerking voert de applicatie een taak uit als onderdeel van hetzelfde verzoek dat een gebruiker of ander systeem heeft gestart. De server ontvangt bijvoorbeeld een formulier, schrijft gegevens naar de database, genereert een rapport en stuurt daarna pas een antwoord terug. De aanvrager krijgt zo direct het resultaat, of een foutmelding als een stap mislukt. Dat maakt het model overzichtelijk: de volgorde van bewerkingen ligt vast binnen één verzoek en de gebruiker hoeft geen aparte taakstatus op te vragen.

Het model werkt goed zolang de verwerking kort en voorspelbaar is. Een eenvoudige databasewijziging of berekening kan meestal binnen de normale responstijd worden afgehandeld. De grens wordt zichtbaar wanneer de taak afhankelijk is van trage externe diensten, grote bestanden of variabele hoeveelheden data. De verbinding blijft open, servercapaciteit is bezet en een timeout kan optreden voordat de taak klaar is. Bovendien weet een client na een verbroken verbinding niet altijd of de bewerking al is uitgevoerd.

Synchroon betekent niet automatisch één database-transactie of één proces. Een applicatie kan meerdere services aanroepen, maar zolang het antwoord ervan afhangt, blijft de gebruiker wachten. Beoordeel daarom niet alleen de gemiddelde verwerkingstijd. Ook piekbelasting, variatie en foutgedrag bepalen of directe afhandeling beheersbaar blijft.

Gebruikerservaring en responstijd bij lang werk

De zichtbare consequentie van een langlopend verzoek is vaak een interface die blijft laden. Dat kan aanvaardbaar zijn wanneer de gebruiker een duidelijke actie uitvoert en het resultaat direct nodig heeft, maar het wordt problematisch als de voortgang onduidelijk is of de wachttijd sterk wisselt. Een browser kan een verzoek afbreken, een mobiele verbinding kan wegvallen en een proxy kan na een ingestelde limiet de verbinding sluiten. De onderliggende taak kan dan doorgaan, stoppen of al voltooid zijn; de gebruiker ziet dat niet vanzelf.

Een achtergrondtaak verandert het interactiepatroon. De applicatie bevestigt snel dat de opdracht is ontvangen en geeft bijvoorbeeld een taak-ID terug. De gebruiker kan verder werken terwijl een worker de verwerking uitvoert. Dit vraagt om een passende interface: een statusmelding, een voortgangsindicatie wanneer die betrouwbaar te berekenen is, en een manier om het resultaat later te bekijken. Een voortgangsbalk die alleen een schatting toont zonder relatie met het werk kan juist misleidend zijn.

Een wachtrij maakt verwerking niet per definitie sneller. Ze haalt de lange taak uit het kritieke pad van het verzoek en maakt wachttijd beheersbaar, maar voegt wachttijd in de queue toe. Bij overbelasting kan de totale tijd tot voltooiing dus toenemen. Maak daarom onderscheid tussen snelle bevestiging en daadwerkelijke afronding, zowel in de interface als in de API-documentatie.

Wanneer een achtergrondtaak en job queue passend zijn

Een job queue is nuttig wanneer werk niet binnen de interactie hoeft te worden afgerond en onafhankelijk kan worden uitgevoerd. Denk aan het verwerken van uploads, het genereren van grote exports, het versturen van grote aantallen berichten of het synchroniseren van gegevens met een externe dienst. De webapplicatie plaatst dan een opdracht in de wachtrij en een worker haalt die later op. Daardoor hoeft het proces dat het verzoek ontvangt niet zelf de volledige taak uit te voeren.

Niet elk traag verzoek hoort in een queue. Als een gebruiker een berekening nodig heeft om de volgende stap te kunnen kiezen, kan een achtergrondtaak het proces juist omslachtiger maken. Ook werk met sterke afhankelijkheden tussen opeenvolgende acties vraagt om een zorgvuldig ontwerp: een latere stap mag niet starten voordat de benodigde gegevens bestaan. Soms is een combinatie logisch, waarbij de applicatie eerst een kleine, directe validatie uitvoert en daarna het zware werk overdraagt.

Een praktische toets is om te vragen wat er gebeurt als de aanvrager de verbinding verbreekt. Als het werk dan nog steeds waarde heeft, is het een kandidaat voor asynchrone verwerking. Vraag ook of het resultaat later kan worden opgehaald en of de taak veilig opnieuw kan worden uitgevoerd. Als die vragen moeilijk te beantwoorden zijn, is niet alleen de keuze voor een queue aan de orde; dan moet eerst het proces zelf worden afgebakend.

Taakstatus ontwerpen voor API en gebruikersinterface

Zodra een applicatie werk overdraagt, is een bevestiging van ontvangst iets anders dan een bevestiging van voltooiing. Een API kan na het plaatsen van een taak een identificatie en een status zoals ‘in wachtrij’ teruggeven. De client gebruikt die identificatie om de status op te vragen, bijvoorbeeld via een statusendpoint of een melding wanneer het werk klaar is. Het contract moet duidelijk maken welke statussen bestaan en wat ze betekenen; anders interpreteren clients ‘geaccepteerd’ al snel als ‘uitgevoerd’.

Een bruikbaar statusmodel bevat doorgaans toestanden voor wachten, uitvoeren, geslaagd en mislukt. Afhankelijk van het proces kunnen annulering of een tijdelijke blokkade ook relevant zijn. Leg vast wanneer een taakstatus verandert en welke informatie beschikbaar blijft na voltooiing. Bij een mislukking kan een technische foutcode nuttig zijn voor beheer, terwijl de gebruikersinterface een begrijpelijke, veilige melding toont. Geef geen interne stacktraces of gevoelige gegevens terug aan eindgebruikers.

Polling is eenvoudig te implementeren, maar veroorzaakt herhaalde verzoeken en moet een passende frequentie en stopconditie hebben. Webhooks of servergestuurde meldingen kunnen efficiënter zijn, maar introduceren eigen foutscenario’s: een ontvanger kan tijdelijk onbereikbaar zijn of dezelfde melding meerdere keren ontvangen. Welke methode ook wordt gekozen, statusopslag moet voldoende lang beschikbaar blijven voor de client en beheerders, zonder onbeperkt oude taakgegevens te bewaren.

Wachtrijsemantiek: dubbele uitvoering en idempotentie

Een queue garandeert niet vanzelf dat elke taak precies één keer wordt uitgevoerd. Een worker kan werk uitvoeren en uitvallen voordat de queue de afronding heeft geregistreerd. De taak kan dan opnieuw worden aangeboden. Ook kan een client een verzoek herhalen nadat de bevestiging verloren is gegaan, waardoor dezelfde opdracht meerdere keren wordt aangemaakt. Ontwerp daarom vanuit de mogelijkheid van dubbele uitvoering, tenzij het gekozen systeem en de volledige keten aantoonbaar andere eigenschappen bieden.

Idempotentie betekent dat herhaalde uitvoering niet leidt tot ongewenste extra effecten. Een taak die een rapportbestand genereert, kan bijvoorbeeld hetzelfde resultaat overschrijven op basis van een stabiele taak- of rapport-ID. Een taak die een betaling of externe actie uitvoert, heeft meer bescherming nodig: gebruik een unieke idempotentiesleutel, registreer verwerkte opdrachten en controleer de toestand voordat een effect opnieuw wordt aangevraagd. Een lokale database-transactie voorkomt niet automatisch dubbele effecten bij een externe API.

Ook het moment waarop een opdracht in de queue wordt gezet verdient aandacht. Als de applicatie eerst gegevens opslaat en daarna de queue-aanroep mislukt, bestaat de wijziging zonder bijbehorende taak. In de omgekeerde volgorde kan de worker starten voordat de benodigde gegevens zijn vastgelegd. Een transactionele outbox kan dit gat verkleinen door de domeinwijziging en een uitgaand taakbericht samen op te slaan, waarna een afzonderlijk proces het bericht publiceert. Dat voegt onderdelen toe, maar maakt de grens tussen opslag en queue expliciet.

Retries, mislukte taken en dead-letter queues

Een tijdelijke netwerkfout vraagt om een andere behandeling dan ongeldige invoer. Zonder onderscheid kan een worker een taak eindeloos opnieuw proberen, ook wanneer herhaling niets oplost. Classificeer fouten daarom waar mogelijk als tijdelijk of definitief. Een tijdelijke fout kan aanleiding zijn voor een beperkt aantal retries met oplopende tussenpozen; een definitieve fout hoort doorgaans bij een terminale status die onderzoek of correctie vereist.

Retries kunnen piekbelasting versterken. Als een externe dienst niet beschikbaar is en veel workers dezelfde opdrachten tegelijk opnieuw proberen, ontstaat een retry-storm. Exponentiële back-off, willekeurige spreiding en een maximumaantal pogingen verminderen dat risico. Stel ook vast of de taak veilig opnieuw uitvoerbaar is voordat automatische retries worden ingeschakeld. Zonder idempotentie kan een herhaalde poging bijvoorbeeld een tweede bericht versturen of een externe wijziging dupliceren.

Na het bereiken van de retrygrens kan een taak naar een dead-letter queue of vergelijkbare foutopslag gaan. Die plek is geen eindstation zonder beheer: taken moeten vindbaar zijn, voorzien van voldoende diagnostische context en opnieuw uitvoerbaar zijn nadat de oorzaak is opgelost. Bewaar geen onnodige persoonsgegevens in foutpayloads en voorkom dat een herstart alle mislukte taken tegelijk vrijgeeft. Een operationele procedure beschrijft wie fouten beoordeelt, welke gegevens nodig zijn en onder welke voorwaarden een taak veilig opnieuw wordt gestart.

Worker-capaciteit, wachtrijgroei en terugdruk

Een queue ontkoppelt de snelheid waarmee opdrachten binnenkomen van de snelheid waarmee workers ze verwerken. Dat vangt korte pieken op, maar lost een structurele capaciteitskloof niet op. Als er langdurig meer werk binnenkomt dan workers kunnen afronden, groeit de wachtrij en loopt de tijd tot verwerking op. Een lege queue is daarom geen voldoende maat voor gezondheid; meet ook de ouderdom van de oudste taak, de verwerkingssnelheid en het aantal mislukte opdrachten.

Meer workers toevoegen kan de doorvoer verhogen, maar alleen zolang de onderliggende systemen dat aankunnen. Bij database-intensieve taken kan extra parallelisme verbindingen uitputten of lock-concurrentie verhogen. Een externe API kan een limiet hebben, waardoor opschalen juist meer foutmeldingen oplevert. Stel per taaksoort passende concurrency in en gebruik waar nodig aparte queues. Zo kan een grote export niet alle capaciteit innemen die nodig is voor kleine, tijdgevoelige taken.

Terugdruk is het mechanisme waarmee een systeem overbelasting zichtbaar maakt en begrenst. Dat kan betekenen dat nieuwe opdrachten tijdelijk worden geweigerd, dat de aanvrager later opnieuw probeert of dat taken een prioriteit krijgen. Zonder zo’n grens kan een queue onbeperkt groeien en opslag, geheugen of beheerbaarheid onder druk zetten. Prioriteiten vragen eveneens aandacht: een continue stroom hoge prioriteit kan lage prioriteit permanent verdringen. Meet dus niet alleen totale doorvoer, maar ook wachttijd per categorie en het effect van schaalregels op afhankelijke diensten.

Langlopende taken, voortgang en veilige uitvoering

Een taak die minuten of uren duurt, vraagt om andere keuzes dan een korte achtergrondbewerking. Het is riskant om één workerproces onbeperkt aan één opdracht te binden: een proces kan worden herstart, een machine kan uitvallen en een deploy kan lopend werk onderbreken. Deel waar mogelijk werk op in begrensde, herhaalbare stappen. Sla tussenresultaten duurzaam op en maak duidelijk welke stap al is voltooid, zodat een hervatting niet het hele proces hoeft te herhalen.

Voortgang is alleen betrouwbaar als de taak die kan meten. Bij een export met een bekend aantal records kan de worker verwerkte records rapporteren; bij werk waarvan de omvang pas tijdens uitvoering duidelijk wordt, is een percentage mogelijk schijnprecisie. Een taakstatus kan dan beter aangeven dat verwerking bezig is en wanneer er een betekenisvolle faseovergang plaatsvindt. De interface moet rekening houden met korte statusvertragingen: de worker en de statusopslag werken niet noodzakelijk op exact hetzelfde moment.

Annuleren is eveneens een proceskeuze, geen knop die automatisch een lopende taak stopt. Een worker kan annulering controleren tussen stappen, maar een externe aanroep die al is gestart laat zich mogelijk niet terugdraaien. Beschrijf daarom wat annulering betekent voor gedeeltelijk verwerkte gegevens en eventuele neveneffecten. Beperk daarnaast de rechten van workers tot de gegevens en acties die hun taak nodig heeft. Lange taken verwerken vaak omvangrijke payloads; sla die niet achteloos volledig in de queue op wanneer een beveiligde verwijzing naar duurzame opslag volstaat.

Veelgestelde vragen

Welke gegevens moet ik in een job queue-bericht opnemen?

Neem in een queue-bericht bij voorkeur stabiele identificatiegegevens op en haal de actuele gegevens tijdens de uitvoering op. Een bericht met bijvoorbeeld een order-ID blijft meestal bruikbaarder dan een volledige kopie van een order die later verouderd kan zijn. Zo beperk je ook de hoeveelheid persoonsgegevens en de kans dat gevoelige informatie in logs of queue-opslag belandt.

  • Neem de taaksoort en noodzakelijke identificaties op.
  • Voeg alleen waarden toe die niet betrouwbaar uit een gegevensbron kunnen worden opgehaald.
  • Leg vast hoe een worker omgaat met verwijderde of gewijzigde gegevens.
  • Gebruik een berichtversie als de structuur in de tijd kan veranderen.

Hoe kies ik tussen een databasewachtrij en een aparte message broker?

Kies een databasewachtrij voor eenvoudige, beperkte workloads als je de operationele eenvoud belangrijker vindt dan hoge doorvoer of uitgebreide brokerfuncties. Een aparte message broker is eerder passend wanneer je veel berichten verwerkt, meerdere systemen laat samenwerken of specifieke mogelijkheden nodig hebt voor routering en consumptie. De keuze hangt ook af van wat je team betrouwbaar kan beheren.

  • Beoordeel verwachte berichtvolumes en pieken.
  • Controleer welke garanties en beperkingen het gekozen systeem biedt.
  • Houd rekening met beheer, monitoring, back-ups en herstel.
  • Test de keuze met representatieve workloads in plaats van alleen op theoretische capaciteit te vertrouwen.

Hoe test ik achtergrondtaken betrouwbaar in CI?

Test achtergrondtaken in CI op meerdere niveaus: controleer de taaklogica afzonderlijk en test daarnaast of de queue-integratie berichten correct publiceert en verwerkt. Een unit test kan snel valideren wat er bij geldige en ongeldige invoer gebeurt, maar bewijst niet dat configuratie, serialisatie en worker-verbindingen goed werken. Gebruik voor integratietests bij voorkeur dezelfde soort queue-infrastructuur als in productie.

  • Maak tests voorspelbaar met vaste tijd, invoer en externe afhankelijkheden.
  • Controleer zowel het resultaat als relevante neveneffecten.
  • Test ook foutpaden en berichten met ongeldige of verouderde gegevens.
  • Voorkom dat tests afhankelijk zijn van een gedeelde queue waarin achtergebleven berichten resultaten kunnen beïnvloeden.

Hoe voorkom ik dat een deployment oude queue-taken breekt?

Voorkom problemen bij deployments door nieuwe workers tijdelijk compatibel te houden met berichten die door de vorige versie zijn aangemaakt. Queue-berichten kunnen immers langer blijven bestaan dan een webverzoek of een applicatieproces. Een wijziging in de berichtstructuur of in de betekenis van een veld kan daardoor een oude taak onuitvoerbaar maken, ook als de nieuwe code zelf correct werkt.

  • Maak wijzigingen aan berichten waar mogelijk achterwaarts compatibel.
  • Voeg velden eerst optioneel toe voordat je oude velden verwijdert of hernoemt.
  • Gebruik expliciete berichtversies wanneer compatibiliteit anders onduidelijk wordt.
  • Plan databasewijzigingen zo dat oude en nieuwe workers tijdens een uitrol naast elkaar kunnen werken.

Hoe beveilig ik een API waarmee gebruikers de status van achtergrondtaken bekijken?

Beveilig een status-API door bij elk verzoek te controleren of de ingelogde gebruiker toegang heeft tot de betreffende taak. Een taak-ID is geen vervanging voor autorisatie, ook niet als die moeilijk te raden is. Zonder eigendomscontrole kan een gebruiker mogelijk statusinformatie, foutdetails of resultaten van een andere gebruiker opvragen.

  • Koppel taken aan een gebruiker, organisatie of andere toegangsgrens.
  • Controleer die koppeling bij status- én resultaatverzoeken.
  • Geef aan gebruikers alleen foutinformatie die zij nodig hebben.
  • Beperk misbruik met passende verzoeklimieten en registreer relevante toegang voor beheer.
Portret van Maarten

Maarten

Freelance developer in Nijmegen

Even kennismaken?

Vertel kort wat er speelt. Dan hoor je wat er kan, wat ik anders zou doen en waar AI bij jou wél en niet iets toevoegt. Vrijblijvend.

[email protected]
Het kantoor in Nijmegen
© 2026 maarten.online Sitemap Privacy Algemene voorwaarden
Het kantoor in Nijmegen

Maarten.

Freelance developer in Nijmegen. Liever direct contact? Dat kan ook.

Kennismaken

Laat je gegevens achter, dan kijken we of het klikt. Vrijblijvend en zonder verkooppraat.

Maarten

Stuur een bericht via WhatsApp

Hoi! Waar kan ik je mee helpen?

nu