Retry Policy v mobilním vývoji — podstata, strategie a princip

Autor: IT Sectr Publikováno: 2026-03-11 Doba čtení: 10 min

Retry Policy — politika opakovaných požadavků — sada pravidel určujících, kdy a jak mobilní aplikace automaticky opakuje neúspěšná síťová volání. Při nestabilním připojení nebo dočasných chybách serveru zvyšuje správně navržená politika opakování spolehlivost aplikace bez účasti uživatele. Podle výzkumu Google Developer Relations (2025) správná implementace Retry Policy snižuje procento ztracených požadavků o 40-60 % v mobilních aplikacích s častými síťovými operacemi.

Hlavní body

  • Retry Policy — strategie automatického opakování požadavků při selhání sítě nebo dočasných chybách serveru.
  • Exponential backoff — metoda zvyšování zpoždění mezi opakováními pro snížení zátěže serveru.
  • Jitter — náhodná odchylka zpoždění zabraňující efektu „stáda" (thundering herd).
  • Idempotence — klíčový požadavek pro bezpečná opakování: opakovaný požadavek nesmí způsobovat vedlejší účinky.
  • Circuit Breaker — mechanismus zastavení opakování při dlouhodobé nedostupnosti služby pro úsporu zdrojů.

Co je Retry Policy?

Retry Policy — softwarová strategie určující chování klienta při selhání síťového požadavku: které chyby opakovat, kolikrát, s jakým zpožděním a kdy ukončit pokusy. V mobilních aplikacích je politika opakování kriticky důležitá kvůli nestabilitě mobilních sítí a možným dočasným výpadkům na straně serveru.

Základní Retry Policy zahrnuje tři parametry: maximální počet opakování (maxRetries), počáteční zpoždění (baseDelay) a strategii zvyšování zpoždění (backoff strategy). Dodatečně lze zadat seznam HTTP stavových kódů, na které je třeba reagovat opakováním, a časový limit pro přerušení všech pokusů.

Podle knihy „Designing Data-Intensive Applications" Martina Kleppmanna je 50 % selhání v distribuovaných systémech dočasných a lze je odstranit opakovaným pokusem. To činí Retry Policy jedním z nejúčinnějších a nejlevnějších způsobů, jak zvýšit odolnost mobilní aplikace bez změn architektury serveru.

Které chyby stojí za to opakovat

Dočasné chyby (retriable) — jediný typ selhání, na který by Retry Policy měla reagovat. Patří mezi ně časové limity připojení (SocketTimeoutException), dočasná nedostupnost serveru (HTTP 503, 502) a chyby DNS. Trvalé chyby — HTTP 400, 401, 403, 404 — nemá smysl opakovat, protože ukazují na problém v požadavku, nikoli v síti nebo serveru.

Podle výzkumu AWS Architecture Blog je správná klasifikace chyb na retriable a non-retriable nejdůležitějším rozhodnutím při navrhování Retry Policy. Opakování neidempotentního požadavku s HTTP 401 může vést k zablokování účtu a opakování HTTP 400 k vytvoření duplicit dat. Vždy explicitně konfigurujte seznam kódů pro opakování.

Hlavní strategie opakování

Fixed interval — nejjednodušší strategie: každé opakování se provádí po stejném časovém intervalu. Například při zpoždění 2 sekund aplikace opakuje požadavek po 2, 2, 2 sekundách. Fixed interval je jednoduchý na implementaci a předvídatelný, ale při hromadných selháních vytváří rovnoměrné zatížení serveru.

Incremental interval — zpoždění se lineárně zvyšuje s každým opakováním: první opakování po 1 sekundě, druhé po 2, třetí po 3 a tak dále. Tato strategie dává serveru více času na zotavení při opakujících se selháních, ale je stále předvídatelná pro mnoho klientů, kteří selhávají současně.

StrategieVzorec zpožděníKumulativní čas (3 pokusy)Použití
Fixeddelay = D3 × DJednoduché scénáře, místní časové limity
Incrementaldelay = N × D6 × DPostupné snižování zátěže
Exponentialdelay = D × 2^N7 × DHromadná selhání, cloudové služby
Exponential + Jitterdelay = random(0, D × 2^N)proměnnýVysoká zátěž, mikroslužby

Výběr strategie závisí na povaze aplikace. Pro úkoly na pozadí synchronizace dat na mobilních zařízeních je optimální exponenciální strategie s jitterem — poskytuje nejvyšší pravděpodobnost úspěchu s minimálním zatížením serveru a zařízení uživatele.

Exponential Backoff a Jitter

Exponential backoff — strategie, při které se zpoždění mezi opakováními s každým pokusem zdvojnásobuje. Pokud je počáteční zpoždění 1 sekunda, bude sekvence zpoždění 1, 2, 4, 8, 16 sekund. To dává serveru exponenciálně rostoucí čas na zotavení.

Jitter — náhodná odchylka zpoždění, která zabraňuje synchronním opakovaným požadavkům od mnoha klientů (problém thundering herd). Bez jitteru bude tisíc klientů se stejnou Retry Policy opakovat požadavky současně, což vytvoří špičkové zatížení serveru. Jitter rozkládá opakování v čase.

Implementace v Kotlin s korutinami

Korutiny Kotlinu umožňují implementovat exponential backoff s jitterem bez blokování hlavního vlákna. Funkce retry z knihovny kotlinx-coroutines přijímá podmínku opakování a blok s tělem požadavku, automaticky spravuje zpoždění a počet pokusů.

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!!)
}

Funkce executeWithRetry přijímá lambdu se síťovým voláním a provádí ji s exponential backoff a jitterem. Pokud chyba není opakovatelná (není retriable) nebo je překročen maximální počet pokusů, funkce vrátí chybu. Zpoždění se násobí náhodným koeficientem od 0,5 do 1,5 pro rovnoměrné rozložení opakování.

Circuit Breaker a ukončení opakování

Circuit Breaker — návrhový vzor, který zabraňuje nekonečným opakovaným požadavkům při dlouhodobé nedostupnosti služby. Když počet chyb překročí práh, Circuit Breaker přejde do stavu OPEN a okamžitě vrátí chybu bez provedení požadavku, čímž poskytne serveru čas na zotavení.

V mobilních aplikacích je Circuit Breaker užitečný zejména při nedostupnosti API z důvodu plánované údržby nebo selhání sítě operátora. Bez něj bude aplikace spotřebovávat baterii a přenos dat na nekonečné opakované pokusy, což zhoršuje uživatelský zážitek a zkracuje výdrž baterie zařízení.

Schéma stavů Circuit Breaker

Tři stavy Circuit Breaker: CLOSED (normální provoz, požadavky se provádějí), OPEN (odmítnutí, požadavky jsou blokovány) a HALF_OPEN (zkušební požadavek pro kontrolu zotavení). Po určitém časovém limitu ve stavu OPEN přepínač přejde do HALF_OPEN a provede jeden požadavek — při úspěchu se vrátí do CLOSED, při neúspěchu do 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
        }
    }
}

Implementace Circuit Breaker v Kotlinu obsahuje počítadlo chyb a časovač zotavení. Metoda protect kontroluje aktuální stav před provedením blokovaného požadavku a aktualizuje počítadlo chyb při selháních. Po dosažení prahu failureThreshold jsou všechny požadavky okamžitě odmítnuty do vypršení timeoutMs.

Retry Policy v mobilních aplikacích

Mobilní sítě mají vlastnosti, které činí Retry Policy obzvláště důležitou. Přepínání mezi Wi-Fi a mobilními daty, ztráta signálu v metru a tunelech, dočasné blokace na úrovni operátora — všechny tyto scénáře vedou k selhání požadavků, která jsou úspěšně řešena opakovanými pokusy.

Na Androidu poskytují knihovna Retrofit a OkHttp vestavěný mechanismus RetryPolicy prostřednictvím Interceptoru. Na iOS je problém řešen prostřednictvím URLSessionConfiguration a vlastního delegování. Pro multiplatformní vývoj obsahuje Ktor (KMP) vestavěnou podporu retry s konfigurovatelnými strategiemi.

Implementace na iOS s Combine

Combine — framework Apple pro reaktivní programování. Operátor retry v Combine opakuje publisher při chybě určitý počet opakování, ale neumožňuje konfigurovat zpoždění mezi opakováními. Pro plnohodnotnou Retry Policy se používá vlastní kombinace catch a flatMap se zpožděním.

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()
    }
}

Rozšíření retryWithBackoff pro Publisher v Combine implementuje exponential backoff prostřednictvím rekurzivního volání se snižováním počítadla a zdvojnásobováním zpoždění. Operátor delay vytváří pauzu mezi opakováními a catch zachycuje chybu a rozhoduje, zda se pokusit znovu nebo vrátit failure.

Typické chyby při Retry Policy

První chyba — opakování požadavků bez kontroly idempotence. Pokud server vytvořil zdroj, ale nevrátil potvrzení kvůli selhání sítě, opakovaný požadavek vytvoří duplikát. Pro požadavky POST vždy používejte idempotentní klíč (Idempotency-Key) v záhlaví nebo přejděte na retry pouze pro GET, PUT a DELETE.

Druhá chyba — nekonečná opakování (retry forever). Vždy nastavte maximální počet pokusů (3-5 pro mobilní aplikace) a celkový časový limit pro všechny pokusy. Nekonečná opakování vybíjejí baterii a vytvářejí parazitní zatížení serveru, zejména při migraci databází nebo změně API.

Třetí chyba — ignorování kontextu aplikace. Pokud uživatel zavřel aplikaci nebo přešel do režimu na pozadí, aktivní Retry Policy by měly být správně zrušeny. Používejte korutiny s SupervisorScope nebo Combine s životním cyklem UI pro automatické zrušení opakování při zavření obrazovky.

Čtvrtá chyba — neprotokolování opakovaných pokusů. Bez protokolování nebudete vědět, kolik požadavků bylo opakováno, jaké chyby se vyskytly a jak účinná je vaše Retry Policy. Přidejte metriky: počet opakování, úspěšnost po opakování, rozložení zpoždění. Tato data pomohou nastavit optimální parametry strategie pro konkrétní aplikaci.

Často kladené otázky

Kolikrát opakovat požadavek v mobilní aplikaci?

Optimální počet opakování — 3-5 pokusů pro většinu scénářů. Pro synchronizaci na pozadí je povoleno 5-7 pokusů, pro interaktivní požadavky (např. odeslání formuláře) — ne více než 3. Větší počet opakování nezvyšuje pravděpodobnost úspěchu, ale spotřebovává baterii a přenos dat uživatele.

Co je exponential backoff jednoduchými slovy?

Exponential backoff — zdvojnásobování zpoždění mezi opakovanými pokusy: 1 sekunda, 2, 4, 8, 16 a tak dále. Pokud je server přetížený, krátká pauza mezi prvními opakováními mu umožňuje rychle odpovědět a rostoucí pauza s každým dalším pokusem dává serveru stále více času na zotavení.

Které HTTP stavové kódy stojí za to opakovat?

Opakujte pouze dočasné chyby: 408 (Request Timeout), 429 (Too Many Requests), 502 (Bad Gateway), 503 (Service Unavailable), 504 (Gateway Timeout). Chyby 4xx (kromě 408 a 429) ukazují na problémy klienta — jejich opakování nemá smysl a může být nebezpečné pro data uživatele.

Čím se liší Retry Policy od Circuit Breaker?

Retry Policy řídí opakování jednoho požadavku při selhání. Circuit Breaker řídí stav připojení ke službě: při nahromadění chyb otevře okruh (OPEN) a neumožňuje nové požadavky. Retry funguje na úrovni jednotlivého volání, Circuit Breaker — na úrovni integrace se službou.

Jak testovat Retry Policy na mobilních zařízeních?

Pro testování Retry Policy použijte NetworkInterceptor (OkHttp) na Androidu a URLProtocol (URLSession) na iOS pro simulaci selhání sítě. Nastavte parametry: frekvenci chyb, dobu nedostupnosti a kódy odpovědí. Unit testy s MockWebServer (OkHttp) nebo OHHTTPStubs (iOS) kontrolují logiku opakování bez reálné sítě.

Shrnutí

  • Retry Policy — strategie automatického opakování síťových požadavků při dočasných selháních s konfigurovatelnými parametry zpoždění a počtu pokusů.
  • Exponential backoff s jitterem — základní strategie pro mobilní aplikace, snižující zatížení serveru při hromadných selháních a zabraňující efektu thundering herd.
  • Idempotence — povinná podmínka pro bezpečné opakování ne-GET požadavků: bez ní opakování vytváří duplicity dat nebo nežádoucí vedlejší účinky.
  • Circuit Breaker doplňuje Retry Policy, zabraňuje nekonečným opakováním při dlouhodobé nedostupnosti služby a šetří zdroje zařízení.
  • Klasifikace chyb — rozdělení na retriable (503, 502, timeout) a non-retriable (400, 401, 403) je kritické pro správnou funkci politiky opakování.
  • Maximálně 3-5 opakování v interaktivních scénářích a až 7 pro synchronizaci na pozadí — optimální hodnota pro mobilní aplikace podle Google Developer Relations.
  • Doporučení — implementujte Retry Policy s exponential backoff, Circuit Breaker a protokolováním pro všechny síťové požadavky v mobilní aplikaci.

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také