Retry Policy inom mobilutveckling — essens, strategier och princip

Författare: IT Sectr Publicerad: 2026-03-11 Lästid: 10 min

Retry Policy — policy för upprepade förfrågningar — en uppsättning regler som avgör när och hur en mobilapp automatiskt upprepar misslyckade nätverksanrop. Vid instabil anslutning eller tillfälliga serverfel ökar en väl utformad upprepningspolicy appens tillförlitlighet utan användarens inblandning. Enligt forskning från Google Developer Relations (2025) minskar korrekt implementering av Retry Policy andelen förlorade förfrågningar med 40-60 % i mobilappar med frekventa nätverksoperationer.

Huvudpunkter

  • Retry Policy — strategi för automatisk upprepning av förfrågningar vid nätverksfel eller tillfälliga serverfel.
  • Exponential backoff — metod för att öka fördröjningen mellan upprepningar för att minska serverbelastningen.
  • Jitter — slumpmässig avvikelse i fördröjning som förhindrar “kluster”-effekten (thundering herd).
  • Idempotens — nyckelkravet för säkra upprepningar: en upprepad förfrågan får inte orsaka biverkningar.
  • Circuit Breaker — mekanism för att stoppa upprepningar vid långvarig otillgänglighet av tjänsten för att spara resurser.

Vad är Retry Policy?

Retry Policy — är en mjukvarustrategi som bestämmer klientens beteende vid ett misslyckat nätverksanrop: vilka fel som ska upprepas, hur många gånger, med vilken fördröjning och när försöken ska avbrytas. I mobilappar är upprepningspolicyn kritisk på grund av instabiliteten i mobila nätverk och möjliga tillfälliga fel på serversidan.

Grundläggande Retry Policy omfattar tre parametrar: maximalt antal upprepningar (maxRetries), initial fördröjning (baseDelay) och strategi för att öka fördröjningen (backoff strategy). Dessutom kan en lista över HTTP-statuskoder som ska besvaras med upprepning anges, samt en timeout för att avbryta alla försök.

Enligt boken “Designing Data-Intensive Applications” av Martin Kleppmann är 50 % av felen i distribuerade system tillfälliga och åtgärdas vid ett nytt försök. Detta gör Retry Policy till ett av de mest effektiva och billigaste sätten att öka feltoleransen hos en mobilapp utan att ändra serverarkitekturen.

Vilka fel är värda att upprepa

Tillfälliga fel (retriable) — den enda typen av fel som Retry Policy bör reagera på. Dessa inkluderar anslutningstimeout (SocketTimeoutException), tillfällig otillgänglighet av servern (HTTP 503, 502) och DNS-fel. Permanenta fel — HTTP 400, 401, 403, 404 — är meningslösa att upprepa eftersom de indikerar ett problem i förfrågan, inte i nätverket eller servern.

Enligt forskning från AWS Architecture Blog är korrekt klassificering av fel i retriable och non-retriable det viktigaste beslutet vid utformning av Retry Policy. Upprepning av en icke-idempotent förfrågan med HTTP 401 kan leda till blockering av kontot, och upprepning av HTTP 400 till skapande av dubbletter av data. Konfigurera alltid listan över koder för upprepning explicit.

Huvudsakliga upprepningsstrategier

Fixed interval — den enklaste strategin: varje upprepning utförs efter samma tidsintervall. Till exempel, med en fördröjning på 2 sekunder upprepar appen förfrågan efter 2, 2, 2 sekunder. Fixed interval är enkel att implementera och förutsägbar, men skapar en jämn belastning på servern vid massfel.

Incremental interval — fördröjningen ökar linjärt med varje upprepning: första upprepningen efter 1 sekund, andra efter 2, tredje efter 3, och så vidare. Denna strategi ger servern mer tid att återhämta sig vid upprepade fel, men är fortfarande förutsägbar för många klienter som misslyckas samtidigt.

StrategiFormel för fördröjningKumulativ tid (3 försök)Tillämpning
Fixeddelay = D3 × DEnkla scenarier, lokala timeout
Incrementaldelay = N × D6 × DStegvis minskning av belastning
Exponentialdelay = D × 2^N7 × DMassfel, molntjänster
Exponential + Jitterdelay = random(0, D × 2^N)variabelHög belastning, mikrotjänster

Valet av strategi beror på appens natur. För bakgrundsuppgifter för datasynkronisering på mobila enheter är exponentialstrategin med jitter optimal — den ger högsta sannolikhet för framgång med minimal belastning på servern och användarens enhet.

Exponential Backoff och Jitter

Exponential backoff — strategi där fördröjningen mellan upprepningar fördubblas med varje försök. Om den initiala fördröjningen är 1 sekund blir sekvensen av fördröjningar 1, 2, 4, 8, 16 sekunder. Detta ger servern exponentiellt ökande tid att återhämta sig.

Jitter — slumpmässig avvikelse i fördröjning som förhindrar synkrona upprepade förfrågningar från flera klienter (thundering herd-problemet). Utan jitter kommer tusen klienter med samma Retry Policy att upprepa förfrågningar samtidigt, vilket skapar en toppbelastning på servern. Jitter sprider ut upprepningarna i tiden.

Implementering i Kotlin med korutiner

Korutiner i Kotlin gör det möjligt att implementera exponential backoff med jitter utan att blockera huvudtråden. Funktionen retry från kotlinx-coroutines accepterar ett upprepningsvillkor och ett block med förfrågans brödtext, och hanterar automatiskt fördröjningar och antal försök.

kotlin
suspend fun RetryPolicy.executeWithRetry(
    block: suspend () -> Result<T>
): Result<T> {
    var lastError: Throwable? = null
    repeat(maxRetries + 1) { attempt ->
        try {
            return block()
        } catch (e: Exception) {
            if (!isRetriable(e) || attempt == maxRetries) {
                return Result.failure(e)
            }
            val delay = (baseDelayMs * (1 shl attempt))
                .toLong()
            val jitteredDelay = (delay * (0.5 + Random.nextDouble())).toLong()
            delay(jitteredDelay)
            lastError = e
        }
    }
    return Result.failure(lastError!!)
}

Funktionen executeWithRetry accepterar en lambda med ett nätverksanrop och utför det med exponential backoff och jitter. Om felet inte kan upprepas (inte retriable) eller det maximala antalet försök har överskridits, returnerar funktionen felet. Fördröjningen multipliceras med en slumpmässig koefficient mellan 0,5 och 1,5 för en jämn spridning av upprepningar.

Circuit Breaker och att sluta upprepa

Circuit Breaker — ett designmönster som förhindrar oändliga upprepade förfrågningar vid långvarig otillgänglighet av tjänsten. När antalet fel överstiger tröskeln går Circuit Breaker till OPEN-tillståndet och returnerar omedelbart fel utan att utföra förfrågan, vilket ger servern tid att återhämta sig.

I mobilappar är Circuit Breaker särskilt användbart vid otillgänglighet av API på grund av planerat underhåll eller operatörens nätverksfel. Utan det kommer appen att förbruka batteri och trafik på oändliga upprepade försök, vilket försämrar användarupplevelsen och förkortar enhetens batteritid.

Schema över Circuit Breaker-tillstånd

Tre tillstånd för Circuit Breaker: CLOSED (normal drift, förfrågningar utförs), OPEN (avvisning, förfrågningar blockeras) och HALF_OPEN (testförfrågan för att kontrollera återhämtning). Efter en angiven timeout i OPEN-tillståndet går omkopplaren till HALF_OPEN och utför en förfrågan — vid framgång återgår till CLOSED, vid misslyckande — till OPEN.

kotlin
class CircuitBreaker(
    private val failureThreshold: Int = 3,
    private val timeoutMs: Long = 30000
) {
    private var state = State.CLOSED
    private var failureCount = 0
    private var lastFailureTime: Long = 0

    suspend fun T.protect(block: suspend () -> T): T {
        checkState()
        return try {
            val result = block()
            onSuccess()
            result
        } catch (e: Exception) {
            onFailure()
            throw e
        }
    }
}

Implementeringen av Circuit Breaker i Kotlin innehåller en felräknare och en återhämtningstimer. Metoden protect kontrollerar aktuellt tillstånd innan den blockerade förfrågan utförs och uppdaterar felräknaren vid fel. Efter att tröskeln failureThreshold har nåtts avvisas alla förfrågningar omedelbart tills timeoutMs har löpt ut.

Retry Policy i mobilappar

Mobila nätverk har egenskaper som gör Retry Policy särskilt viktig. Växling mellan Wi-Fi och mobildata, signalförlust i tunnelbanan och tunnlar, tillfälliga blockeringar på operatörsnivå — alla dessa scenarier leder till förfrågningsfel som framgångsrikt hanteras genom upprepade försök.

På Android tillhandahåller Retrofit-biblioteket och OkHttp en inbyggd RetryPolicy-mekanism via Interceptor. På iOS löses problemet via URLSessionConfiguration och anpassad delegering. För plattformsoberoende utveckling innehåller Ktor (KMP) inbyggt stöd för retry med konfigurerbara strategier.

Implementering på iOS med Combine

Combine — Apples ramverk för reaktiv programmering. Operatorn retry i Combine upprepar publishern ett angivet antal gånger vid fel, men tillåter inte konfigurering av fördröjningen mellan upprepningar. För en fullständig Retry Policy används en anpassad kombination av catch och flatMap med fördröjning.

swift
extension Publisher {
    func retryWithBackoff(
        retries: Int = 3,
        baseDelay: TimeInterval = 1.0
    ) -> AnyPublisher<Output, Failure> {
        return self.catch { error -> AnyPublisher in
            guard retries > 0 else {
                return Fail(error).eraseToAnyPublisher()
            }
            return Just(())
                .delay(for: .seconds(baseDelay), scheduler: DispatchQueue.main)
                .flatMap { self.retryWithBackoff(
                    retries: retries - 1,
                    baseDelay: baseDelay * 2
                ) }
                .eraseToAnyPublisher()
        }
        .eraseToAnyPublisher()
    }
}

Tillägget retryWithBackoff för Publisher i Combine implementerar exponential backoff genom ett rekursivt anrop med minskning av räknaren och fördubbling av fördröjningen. Operatorn delay skapar en paus mellan upprepningar, och catch fångar upp felet och beslutar om att försöka igen eller returnera failure.

Vanliga misstag vid Retry Policy

Första misstaget — att upprepa förfrågningar utan kontroll av idempotens. Om servern har skapat en resurs men inte returnerat bekräftelse på grund av ett nätverksfel, kommer den upprepade förfrågan att skapa en dubblett. För POST-förfrågningar, använd alltid en idempotent nyckel (Idempotency-Key) i rubriken eller tillämpa retry endast för GET, PUT och DELETE.

Andra misstaget — oändliga upprepningar (retry forever). Ange alltid ett maximalt antal försök (3-5 för mobilappar) och en total timeout för alla försök. Oändliga upprepningar tömmer batteriet och skapar parasitisk belastning på servern, särskilt vid databasmigrering eller API-ändring.

Tredje misstaget — att ignorera appens kontext. Om användaren stängde appen eller gick över till bakgrundsläge, måste aktiva Retry Policy avbrytas korrekt. Använd korutiner med SupervisorScope eller Combine med UI-livscykeln för automatisk avbrytning av upprepningar när skärmen stängs.

Fjärde misstaget — att inte logga upprepade försök. Utan loggning kommer du inte att veta hur många förfrågningar som upprepades, vilka fel som uppstod och hur effektiv din Retry Policy är. Lägg till mätvärden: antal upprepningar, framgång efter upprepning, fördelning av fördröjningar. Dessa data hjälper till att justera optimala strategiparametrar för den specifika appen.

Vanliga frågor

Hur många gånger ska en förfrågan upprepas i en mobilapp?

Det optimala antalet upprepningar — 3-5 försök för de flesta scenarier. För bakgrundssynkronisering är 5-7 försök tillåtna, för interaktiva förfrågningar (t.ex. skicka ett formulär) — inte mer än 3. Fler upprepningar ökar inte sannolikheten för framgång, men förbrukar användarens batteri och datatrafik.

Vad är exponential backoff i enkla ord?

Exponential backoff — fördubbling av fördröjningen mellan upprepade försök: 1 sekund, 2, 4, 8, 16, och så vidare. Om servern är överbelastad gör en kort paus mellan de första upprepningarna att den kan svara snabbt, och den ökande pausen med varje efterföljande försök ger servern allt mer tid att återhämta sig.

Vilka HTTP-statuskoder är värda att upprepa?

Upprepa endast tillfälliga fel: 408 (Request Timeout), 429 (Too Many Requests), 502 (Bad Gateway), 503 (Service Unavailable), 504 (Gateway Timeout). 4xx-fel (utom 408 och 429) indikerar klientproblem — det är meningslöst att upprepa dem och kan vara farligt för användarens data.

Vad är skillnaden mellan Retry Policy och Circuit Breaker?

Retry Policy hanterar upprepning av en enskild förfrågan vid fel. Circuit Breaker hanterar anslutningens status med tjänsten: vid ackumulering av fel öppnas kretsen (OPEN) och nya förfrågningar tillåts inte. Retry fungerar på nivån av ett enskilt anrop, Circuit Breaker — på nivån av integration med tjänsten.

Hur testar man Retry Policy på mobila enheter?

För testning av Retry Policy, använd NetworkInterceptor (OkHttp) på Android och URLProtocol (URLSession) på iOS för att simulera nätverksfel. Ställ in parametrar: feltäthet, varaktighet av otillgänglighet och svarskoder. Enhetstester med MockWebServer (OkHttp) eller OHHTTPStubs (iOS) kontrollerar upprepningslogiken utan verkligt nätverk.

Sammanfattning

  • Retry Policy — strategi för automatisk upprepning av nätverksförfrågningar vid tillfälliga fel med konfigurerbara parametrar för fördröjning och antal försök.
  • Exponential backoff med jitter — grundstrategin för mobilappar, minskar serverbelastningen vid massfel och förhindrar thundering herd-effekten.
  • Idempotens — obligatoriskt villkor för säker upprepning av icke-GET-förfrågningar: utan det skapar upprepning datadubbletter eller oönskade biverkningar.
  • Circuit Breaker kompletterar Retry Policy, förhindrar oändliga upprepningar vid långvarig otillgänglighet av tjänsten och sparar enhetens resurser.
  • Felklassificering — uppdelning i retriable (503, 502, timeout) och non-retriable (400, 401, 403) är kritisk för korrekt funktion av upprepningspolicyn.
  • Maximalt 3-5 upprepningar i interaktiva scenarier och upp till 7 för bakgrundssynkronisering — optimalt värde för mobilappar enligt Google Developer Relations.
  • Rekommendation — implementera Retry Policy med exponential backoff, Circuit Breaker och loggning för alla nätverksförfrågningar i mobilappen.

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också