15 mrt 2025·6 min leestijd

Go context-timeouts voor API's: van HTTP-handlers tot SQL

Go context-timeouts voor API's helpen deadlines door te geven van HTTP-handlers naar SQL, voorkomen vastlopende requests en houden services stabiel onder load.

Go context-timeouts voor API's: van HTTP-handlers tot SQL

Waarom requests vastlopen (en waarom dat onder load pijn doet)

Een request raakt “vast” wanneer het wacht op iets dat niet terugkeert: een trage databasequery, een geblokkeerde verbinding uit de pool, een DNS-hiccup of een upstream-service die de oproep accepteert maar nooit antwoordt.

Het symptoom lijkt eenvoudig: sommige requests duren eindeloos, en er stapelen zich meer en meer achter hen op. Vaak zie je toenemend geheugengebruik, een groeiend aantal goroutines en een rij open verbindingen die maar niet leegloopt.

Onder load doet een vastgelopen request twee keer kwaad. Ze houden workers bezet en ze houden schaarse resources vast zoals databaseverbindingen en locks. Dat maakt normaal snelle requests langzaam, wat weer meer overlap creëert, en nog meer wachten.

Retries en verkeerspieken verergeren deze spiraal. Een client timet uit en retryt terwijl het oorspronkelijke request nog draait, dus betaal je nu voor twee requests. Vermenigvuldig dat met veel clients tijdens een korte vertraging, en je kunt de database overbelasten of connection limits raken, zelfs als het gemiddelde verkeer prima is.

Een timeout is simpel gezegd een belofte: “we wachten niet langer dan X.” Het helpt je snel te falen en resources vrij te geven, maar het maakt werk niet sneller af.

Het garandeert ook niet dat het werk meteen stopt. De database kan doorgaan met uitvoeren, een upstream-service kan je annulering negeren, of je eigen code is mogelijk niet veilig voor annulering.

Wat een timeout wel garandeert, is dat je handler kan stoppen met wachten, een duidelijke fout kan teruggeven en kan vrijgeven wat hij vasthoudt. Die begrensde wachttijd voorkomt dat een paar trage calls uitgroeien tot een volledige outage.

Het doel met Go context timeouts is één gedeelde deadline van de rand tot aan de diepste call. Stel het eenmaal in bij de HTTP-grens, geef dezelfde context door door je servicecode en gebruik het in database/sql-calls zodat de database ook te horen krijgt wanneer hij moet stoppen met wachten.

Context in Go in gewone taal

Een context.Context is een klein object dat je door je code meegeeft om te beschrijven wat er nu gebeurt. Het beantwoordt vragen als: “Is dit request nog geldig?”, “Wanneer moeten we opgeven?” en “Welke request-gescopeerde waarden gaan mee met dit werk?”

De grote winst is dat één beslissing aan de rand van je systeem (je HTTP-handler) elke downstream stap kan beschermen, zolang je dezelfde context blijft doorgeven.

Wat context meedraagt

Context is geen plek voor businessdata. Het is bedoeld voor controlesignalen en een kleine hoeveelheid request-scope: cancelatie, een deadline/timeout en kleine metadata zoals een request-id voor logs.

Timeout versus cancelatie is eenvoudig: een timeout is één reden voor cancelatie. Als je een timeout van 2 seconden instelt, wordt de context geannuleerd na 2 seconden. Maar een context kan ook eerder geannuleerd worden als de gebruiker het tabblad sluit, de load balancer de verbinding verbreekt of je code besluit dat het request moet stoppen.

Context stroomt door functieroeps heen als een expliciet parameter, meestal de eerste: func DoThing(ctx context.Context, ...). Dat is het punt. Het is moeilijk om het te “vergeten” wanneer het bij elke call zichtbaar is.

Wanneer de deadline verloopt, moet alles dat naar die context kijkt snel stoppen. Bijvoorbeeld: een databasequery met QueryContext zou vroeg moeten terugkeren met een fout zoals context deadline exceeded, en je handler kan reageren met een timeout in plaats van te hangen totdat de server door zijn workers heen is.

Een goed mentaal model: één request, één context, overal doorgeven. Als het request stopt, moet het werk ook stoppen.

Een duidelijke deadline instellen bij de HTTP-grens

Als je end-to-end timeouts wilt laten werken, beslis waar de klok start. De veiligste plek is direct bij de HTTP-edge, zodat elke downstream call (businesslogica, SQL, andere services) dezelfde deadline erft.

Je kunt die deadline op een paar plaatsen instellen. Server-level timeouts zijn een goede basis en beschermen je tegen trage clients. Middleware is fijn voor consistentie over routegroepen. Het in de handler zelf instellen is ook prima wanneer je iets expliciets en lokaals wilt.

Voor de meeste API's zijn per-request timeouts in middleware of de handler het makkelijkst te beredeneren. Houd ze realistisch: gebruikers geven de voorkeur aan een snelle, duidelijke fout boven een request dat blijft hangen. Veel teams gebruiken kortere budgets voor reads (bijv. 1–2s) en iets langere voor writes (bijv. 3–10s), afhankelijk van wat het endpoint doet.

Hier is een simpel handler-patroon:

func (s *Server) getReport(w http.ResponseWriter, r *http.Request) {
    ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)
    defer cancel()

    report, err := s.reports.Generate(ctx, r.URL.Query().Get("id"))
    if err != nil {
        http.Error(w, err.Error(), http.StatusGatewayTimeout)
        return
    }

    json.NewEncoder(w).Encode(report)
}

Twee regels houden dit effectief:

  • Roep altijd cancel() aan zodat timers en resources snel worden vrijgegeven.
  • Vervang de request-context nooit met context.Background() of context.TODO() binnen de handler. Dat breekt de keten, en je database-calls en outbound requests kunnen blijven draaien nadat de client verdwenen is.

Context door je codebase propagateren

Zodra je een deadline bij de HTTP-grens instelt, is het echte werk ervoor zorgen dat diezelfde deadline elke laag bereikt die kan blokkeren. Het idee is één klok, gedeeld door de handler, servicecode en alles dat netwerk of schijf aanraakt.

Een simpele regel houdt dingen consistent: elke functie die kan wachten moet een context.Context accepteren en het moet de eerste parameter zijn. Dat maakt het duidelijk op callsites en het wordt een gewoonte.

Een praktisch signature-patroon

Geef de voorkeur aan signatures zoals DoThing(ctx context.Context, ...) voor services en repositories. Vermijd het verbergen van context in structs of het opnieuw aanmaken met context.Background() in lagere lagen, want dat verliest stilletjes de deadline van de caller.

func (h *Handler) CreateOrder(w http.ResponseWriter, r *http.Request) {
    ctx := r.Context()

    if err := h.svc.CreateOrder(ctx, r.Body); err != nil {
        // map context errors to a clear client response elsewhere
        http.Error(w, err.Error(), http.StatusRequestTimeout)
        return
    }
}

func (s *Service) CreateOrder(ctx context.Context, body io.Reader) error {
    // parsing or validation can still respect cancellation
    select {
    case <-ctx.Done():
        return ctx.Err()
    default:
    }

    return s.repo.InsertOrder(ctx, /* data */)
}

Vroege exits netjes afhandelen

Behandel ctx.Done() als een normale controlepad. Twee gewoonten helpen:

  • Controleer ctx.Err() voordat je duur werk start en na lange lussen.
  • Geef ctx.Err() onveranderd omhoog terug, zodat de handler snel kan reageren en geen resources meer verspilt.

Wanneer elke laag dezelfde ctx doorgeeft, kan één timeout parsing, businesslogica en database-wachten in één keer afkappen.

Deadlines toepassen op database/sql-queries

Deploy waar je stack draait
Start apps op AppMaster Cloud of op je eigen AWS, Azure of Google Cloud.
Deploy app

Zodra je HTTP-handler een deadline heeft, zorg dan dat je databasewerk er daadwerkelijk naar luistert. Met database/sql betekent dat: gebruik altijd de context-aware methoden. Als je Query() of Exec() zonder context aanroept, kan je API blijven wachten op een trage query zelfs nadat de client heeft opgegeven.

Gebruik consequent: db.QueryContext, db.QueryRowContext, db.ExecContext en db.PrepareContext (en daarna QueryContext/ExecContext op de teruggegeven statement).

func (s *Store) GetUser(ctx context.Context, id int64) (*User, error) {
	row := s.db.QueryRowContext(ctx,
		`SELECT id, email FROM users WHERE id = $1`, id,
	)
	var u User
	if err := row.Scan(&u.ID, &u.Email); err != nil {
		return nil, err
	}
	return &u, nil
}

func (s *Store) UpdateEmail(ctx context.Context, id int64, email string) error {
	_, err := s.db.ExecContext(ctx,
		`UPDATE users SET email = $1 WHERE id = $2`, email, id,
	)
	return err
}

Twee dingen zijn makkelijk te missen.

Ten eerste moet je SQL-driver context-cancelatie respecteren. Veel drivers doen dat, maar controleer het in je stack door een opzettelijk trage query te testen en te controleren of die snel geannuleerd wordt wanneer de deadline is bereikt.

Ten tweede, overweeg een database-side timeout als backstop. Bijvoorbeeld: Postgres kan een per-statement limiet afdwingen (meestal statement_timeout). Dat beschermt de database zelfs als er ergens een bug is die context vergeet door te geven.

Wanneer een operatie stopt vanwege een timeout, behandel dat anders dan een normale SQL-fout. Controleer errors.Is(err, context.DeadlineExceeded) en errors.Is(err, context.Canceled) en geef een duidelijke response terug (zoals een 504) in plaats van te doen alsof de database kapot is. Als je Go-backends genereert (bijv. met AppMaster), maakt het onderscheid houden tussen deze foutpaden logs en retries ook makkelijker te begrijpen.

Downstream calls: HTTP-clients, caches en andere services

Zelfs als je handler en SQL-queries context respecteren, kan een request nog steeds hangen als een downstream call eeuwig wacht. Onder load kunnen een paar vastgelopen goroutines zich opstapelen, connection pools opeten en een kleine vertraging veranderen in een volledige outage. De oplossing is consistente propagatie met een harde backstop.

Outbound HTTP

Bij het aanroepen van een andere API, maak het request met dezelfde context zodat deadline en cancelatie automatisch meeliften.

req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil { /* handle */ }
resp, err := httpClient.Do(req)

Vertrouw niet alleen op context. Configureer ook de HTTP-client en transport zodat je beschermd bent als code per ongeluk een background-context gebruikt, of als DNS/TLS/idle connections vastlopen. Stel http.Client.Timeout in als een bovenlimiet voor de hele call, stel transport-timeouts in (dial, TLS-handshake, response header) en hergebruik één client in plaats van er per request een nieuwe te maken.

Caches en queues

Caches, message brokers en RPC-clients hebben vaak hun eigen wachtroutines: verkrijgen van een verbinding, wachten op een reply, blokkeren op een volle queue of wachten op een lock. Zorg dat die operaties ctx accepteren en gebruik library-level timeouts waar mogelijk.

Een praktische regel: als het gebruikersrequest nog 800ms over heeft, begin dan niet aan een downstream-call die 2 seconden kan duren. Sla het over, degradeer of geef een gedeeltelijk antwoord.

Bepaal van tevoren wat een timeout voor je API betekent. Soms is het juiste antwoord een snelle fout. Soms is het gedeeltelijke data voor optionele velden. Soms is het verouderde cache-data, duidelijk gemarkeerd.

Als je Go-backends bouwt (inclusief gegenereerde, zoals in AppMaster), is dit het verschil tussen “timeouts bestaan” en “timeouts beschermen het systeem consistent” tijdens verkeerspieken.

Stapsgewijs: refactor een API om end-to-end timeouts te gebruiken

Bouw API's met duidelijke timeouts
Maak een Go-backend in AppMaster en houd deadlines consistent van handler tot SQL.
Probeer AppMaster

Refactoren voor timeouts komt neer op één gewoonte: geef dezelfde context.Context van de HTTP-edge helemaal door naar elke call die kan blokkeren.

Een praktische manier is top-down werken:

  • Verander je handler en core servicemethoden zodat ze ctx context.Context accepteren.
  • Werk elke DB-call bij naar QueryContext of ExecContext.
  • Doe hetzelfde voor externe calls (HTTP-clients, caches, queues). Als een library geen ctx accepteert, wrapp het of vervang het.
  • Beslis wie timeouts beheert. Een veelgebruikte regel is: de handler stelt de totale deadline in; lagere lagen mogen alleen kortere deadlines instellen wanneer dat nodig is.
  • Maak fouten voorspelbaar aan de rand: map context.DeadlineExceeded en context.Canceled naar duidelijke HTTP-responses.

Dit is de gewenste vorm over lagen heen:

func (h *Handler) GetOrder(w http.ResponseWriter, r *http.Request) {
    ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)
    defer cancel()

    order, err := h.svc.GetOrder(ctx, r.PathValue("id"))
    if errors.Is(err, context.DeadlineExceeded) {
        http.Error(w, "request timed out", http.StatusGatewayTimeout)
        return
    }
    if err != nil {
        http.Error(w, "internal error", http.StatusInternalServerError)
        return
    }
    _ = json.NewEncoder(w).Encode(order)
}

func (r *Repo) GetOrder(ctx context.Context, id string) (Order, error) {
    row := r.db.QueryRowContext(ctx, `SELECT id,total FROM orders WHERE id=$1`, id)
    // scan...
}

Timeout-waarden moeten saai en consistent zijn. Als de handler 2 seconden totaal heeft, houd DB-queries onder 1 seconde om ruimte over te laten voor JSON-encoding en ander werk.

Om te bewijzen dat het werkt, voeg een test toe die een timeout forceert. Een eenvoudige aanpak is een fake repository-methode die blokkeert tot ctx.Done() en dan ctx.Err() teruggeeft. Je test moet asserten dat de handler snel een 504 teruggeeft, niet pas na de fake vertraging.

Als je Go-backends genereert met een generator (bijv. AppMaster), blijft de regel hetzelfde: één request-context, doorgevoerd overal, met duidelijke eigenaar van de deadline.

Observability: aantonen dat timeouts werken

Verbind veelgebruikte services snel
Integreer auth, betalingen en messaging modules zonder steeds dezelfde plumbing te schrijven.
Ontdek modules

Timeouts helpen alleen als je ze kunt zien gebeuren. Het doel is simpel: elk request heeft een deadline, en wanneer het faalt kun je zien waar de tijd naartoe ging.

Begin met logs die veilig en nuttig zijn. In plaats van volledige request-bodies te dumpen, log genoeg om de draad te volgen en trage paden te zien: request-id (of trace-id), of er een deadline is ingesteld en hoeveel tijd er nog over is op belangrijke punten, de operatie-naam (handler, SQL-querynaam, outbound call-naam) en de resultaatcategorie (ok, timeout, canceled, andere fout).

Voeg een paar gerichte metrics toe zodat gedrag onder load duidelijk is:

  • Aantal timeouts per endpoint en afhankelijkheid
  • Request-latency (p50/p95/p99)
  • In-flight requests
  • Database-query-latency (p95/p99)
  • Foutpercentage uitgesplitst op type

Bij het afhandelen van fouten, tag ze correct. context.DeadlineExceeded betekent meestal dat je budget op is geraakt. context.Canceled betekent vaak dat de client is weggegaan of een upstream timeout eerst afging. Houd deze apart omdat de oplossingen verschillen.

Tracing: vind waar de tijd wegvloeide

Tracing-spans moeten dezelfde context volgen van de HTTP-handler in database/sql-calls zoals QueryContext. Stel dat een request om 2 seconden time-out en de trace toont 1.8 seconden wachten op een DB-verbinding. Dat wijst op poolgrootte of trage transacties, niet op de querytekst.

Als je een intern dashboard bouwt (timeouts per route, top trage queries), kan een no-code tool zoals AppMaster je helpen het snel uit te rollen zonder observability als apart engineeringproject te maken.

Veelgemaakte fouten die je timeouts tenietdoen

De meeste “het hangt soms nog steeds” bugs komen door een paar kleine fouten.

  • Resetten van de klok onderweg. Een handler zet een 2s-deadline, maar de repository maakt een nieuwe context met een andere timeout (of geen timeout). Nu kan de database doorgaan nadat de client weg is. Geef de inkomende ctx door en verscherp hem alleen als je een duidelijke reden hebt.
  • Goroutines starten die nooit stoppen. Werk starten met context.Background() (of de ctx helemaal weggooien) betekent dat het blijft draaien nadat het request is geannuleerd. Geef de request-ctx door naar goroutines en select op ctx.Done().
  • Deadlines die te kort zijn voor echt verkeer. Een 50ms-timeout werkt misschien op je laptop maar faalt in productie tijdens een kleine spike, wat retries, meer load en een door jezelf veroorzaakte mini-outage veroorzaakt. Kies timeouts op basis van normale latencies plus marge.
  • De echte fout verbergen. context.DeadlineExceeded behandelen als een generieke 500 maakt debugging en clientgedrag erger. Map het naar een duidelijke timeout-response en log het verschil tussen “geannuleerd door client” en “getimed out”.
  • Resources openlaten bij vroege exits. Als je vroeg terugkeert, zorg dat je nog steeds defer rows.Close() doet en de cancel-functie van context.WithTimeout aanroept. Gelekte rows of lingering werk kan verbindingen onder load uitputten.

Een snel voorbeeld: een endpoint start een rapportquery. Als de gebruiker het tabblad sluit, wordt de handler-ctx geannuleerd. Als je SQL-call een nieuwe background-context gebruikte, draait de query nog steeds en houdt een verbinding vast, waardoor iedereen vertraagt. Wanneer je dezelfde ctx in QueryContext doorgeeft, wordt de database-call afgebroken en herstelt het systeem sneller.

Snelle checklist voor betrouwbare timeout-gedragingen

Begin vanaf een werkend template
Start vanaf een werkend template en iterereer snel als eisen veranderen.
Aan de slag

Timeouts helpen alleen als ze consistent zijn. Eén gemiste call kan een goroutine bezet houden, een DB-verbinding vasthouden en volgende requests vertragen.

  • Stel één duidelijke deadline aan de rand in (meestal de HTTP-handler). Alles binnen het request erft die.
  • Geef dezelfde ctx door in je service- en repositorylagen. Vermijd context.Background() in request-code.
  • Gebruik context-aware DB-methoden overal: QueryContext, QueryRowContext en ExecContext.
  • Bevestig dezelfde ctx aan outbound-calls (HTTP-clients, caches, queues). Als je een child-context maakt, maak hem korter, niet langer.
  • Handel cancelaties en timeouts consistent af: geef een schone fout terug, stop werk en vermijd retry-loops binnen een geannuleerd request.

Controleer daarna gedrag onder druk. Een timeout die afgaat maar resources niet snel genoeg vrijgeeft, schaadt nog steeds de betrouwbaarheid.

Dashboards moeten timeouts duidelijk maken, niet verbergen in gemiddelden. Volg een paar signalen die de vraag beantwoorden “worden deadlines echt afgedwongen?”: request-timeouts en DB-timeouts (apart), latency-percentielen (p95, p99), DB-poolstatistieken (in-use connections, wait count, wait duration) en een uitsplitsing van foutoorzaken (context deadline exceeded vs andere failures).

Als je interne tools bouwt op een platform zoals AppMaster, geldt dezelfde checklist voor alle Go-services die je ermee verbindt: definieer deadlines aan de rand, propagateer ze en bevestig in metrics dat vastgelopen requests snelle failures worden in plaats van langzame opstoppingen.

Voorbeeldscenario en volgende stappen

Een veelvoorkomende plek waar dit rendeert is een zoek-endpoint. Stel GET /search?q=printer vertraagt wanneer de database druk is met een grote rapportquery. Zonder deadline kan elk inkomend request blijven wachten op een lange SQL-query. Onder load stapelen die vastgelopen requests zich op, bezetten worker-goroutines en verbindingen en voelt de hele API zich vast.

Met een duidelijke deadline in de HTTP-handler en dezelfde ctx naar je repository, stopt het systeem met wachten wanneer het budget op is. Wanneer de deadline bereikt is, annuleert de database-driver de query (indien ondersteund), geeft de handler terug en kan de server nieuwe requests blijven bedienen in plaats van eeuwig te wachten.

Het gebruikerszicht is beter, zelfs wanneer er iets misgaat. In plaats van 30–120 seconden te draaien en dan rommelig te falen, krijgt de client een snelle, voorspelbare fout (vaak 504 of 503 met een korte boodschap zoals “request timed out”). Belangrijker: het systeem herstelt sneller omdat nieuwe requests niet achter oude geblokkeerde requests komen te staan.

Volgende stappen om dit door endpoints en teams heen te verankeren:

  • Kies standaard timeouts per endpointtype (search vs writes vs exports).
  • Vereis QueryContext en ExecContext in code reviews.
  • Maak timeout-fouten expliciet aan de rand (duidelijk statuscode, eenvoudige boodschap).
  • Voeg metrics toe voor timeouts en cancelaties zodat regressies vroeg worden opgemerkt.
  • Schrijf één helper die contextcreatie en logging wrappet zodat elke handler hetzelfde gedrag vertoont.

Als je services en interne tools bouwt met AppMaster, kun je deze timeout-regels consistent toepassen over gegenereerde Go-backends, API-integraties en dashboards op één plek. AppMaster is beschikbaar op appmaster.io (no-code, met echte Go-brongecode-generatie), dus het kan praktisch zijn wanneer je consistente request-afhandeling en observability wilt zonder elke admin-tool handmatig te bouwen.

FAQ

Wat betekent het wanneer een request “vastloopt” in een Go API?

Een request is “vastgelopen” wanneer het wacht op iets dat niet terugkeert, zoals een trage SQL-query, een geblokkeerde verbinding uit de pool, DNS-problemen of een upstream-service die niet reageert. Onder load stapelen vastgelopen requests zich op, bezetten workers en verbindingen, en kunnen een kleine vertraging uitgroeien tot een bredere storing.

Waar moet ik de timeout zetten: middleware, handler of dieper in de code?

Stel de totale deadline in bij de HTTP-grens en geef diezelfde ctx door aan elke laag die kan blokkeren. Die gedeelde deadline voorkomt dat enkele trage operaties resources te lang vasthouden en zo overal timeouts veroorzaken.

Waarom moet ik `cancel()` aanroepen als de timeout toch afloopt?

Gebruik ctx, cancel := context.WithTimeout(r.Context(), d) en doe altijd defer cancel() in de handler (of middleware). De cancel-aanroep maakt timers en andere resources vrij en helpt wachten snel te beëindigen als het request eerder klaar is.

Wat is de grootste fout die timeouts nutteloos maakt?

Vervang de request-context niet door context.Background() of context.TODO() in request-code, want dat verbreekt cancelatie en deadlines. Als je de request-context weggooit, kan downstream werk zoals SQL of outbound HTTP blijven draaien nadat de client is weggegaan.

Hoe moet ik `context deadline exceeded` vs `context canceled` afhandelen?

Behandel context.DeadlineExceeded en context.Canceled als normale uitkomsten en geef ze onveranderd omhoog. Aan de rand map je ze naar duidelijke responses (vaak 504 voor timeouts), zodat clients niet blindelings opnieuw proberen op wat lijkt op een willekeurige 500.

Welke `database/sql`-aanroepen moeten context gebruiken?

Gebruik overal de context-gevoelige methoden: QueryContext, QueryRowContext, ExecContext en PrepareContext. Als je Query() of Exec() zonder context aanroept, kan je handler timen outen terwijl de database-call je goroutine en verbinding blijft bezetten.

Stoppen geannuleerde contexts daadwerkelijk een draaiende PostgreSQL-query?

Veel drivers ondersteunen het, maar verifieer het in jouw stack door een opzettelijk trage query te draaien en te controleren of deze snel terugkeert nadat de deadline is bereikt. Het is ook verstandig om een database-side statement timeout als backstop te gebruiken voor het geval ergens context vergeten wordt.

Hoe pas ik dezelfde deadline toe op outbound HTTP-calls?

Bouw de outbound request met http.NewRequestWithContext(ctx, ...) zodat dezelfde deadline en cancelatie automatisch meeliften. Configureer daarnaast de HTTP-client en transport (timeouts voor dial, TLS-handshake, response header, en een http.Client.Timeout) als harde bovengrens, want context beschermt je niet als iemand per ongeluk background gebruikt of er een lagere-level stall optreedt.

Moeten lagere lagen (repo/services) hun eigen timeouts maken?

Vermijd het creëren van nieuwe contexts die het tijdsbudget in lagere lagen verlengen; child-timeouts moeten korter zijn, niet langer. Als het request weinig tijd over heeft, sla optionele downstream-calls over, geef gedeeltelijke data terug wanneer dat passend is of faal snel met een duidelijk error.

Wat moet ik monitoren om te bewijzen dat end-to-end timeouts werken?

Houd timeouts en cancelaties apart bij endpoint en afhankelijkheid, plus latency-percentielen en in-flight requests. In traces moet dezelfde context van handler naar outbound calls en QueryContext volgen, zodat je kunt zien of tijd is verdwenen in het wachten op een DB-verbinding, het uitvoeren van een query of blokkades bij een andere service.

Gemakkelijk te starten
Maak iets geweldigs

Experimenteer met AppMaster met gratis abonnement.
Als je er klaar voor bent, kun je het juiste abonnement kiezen.

Aan de slag