Retry Policy — takroriy so'rovlar siyosati — mobil ilova muvaffaqiyatsiz tarmoq chaqiruvlarini qachon va qanday avtomatik takrorlashini belgilaydigan qoidalar to'plami. Beqaror ulanish yoki vaqtinchalik server xatolarida to'g'ri takrorlash siyosati foydalanuvchi ishtirokisiz ilovaning ishonchliligini oshiradi. Google Developer Relations (2025) tadqiqotiga ko'ra, Retry Policy ni to'g'ri joriy etish tez-tez tarmoq operatsiyalari bo'lgan mobil ilovalarda yo'qotilgan so'rovlar foizini 40-60% ga kamaytiradi.
Asosiy nuqtalar
Retry Policy — tarmoq so'rovi muvaffaqiyatsiz bo'lganda mijozning xatti-harakatini belgilaydigan dasturiy strategiya: qaysi xatolarni takrorlash, necha marta, qanday kechikish bilan va qachon urinishlarni to'xtatish. Mobil ilovalarda takrorlash siyosati mobil tarmoqlarning beqarorligi va server tomonidagi mumkin bo'lgan vaqtinchalik nosozliklar tufayli juda muhimdir.
Asosiy Retry Policy uch parametrni o'z ichiga oladi: maksimal takrorlash soni (maxRetries), boshlang'ich kechikish (baseDelay) va kechikishni oshirish strategiyasi (backoff strategy). Qo'shimcha ravishda, takror bilan javob beriladigan HTTP statuslari ro'yxati va barcha urinishlarni to'xtatish uchun vaqt chegarasi belgilanishi mumkin.
Martin Kleppmannning “Designing Data-Intensive Applications” kitobiga ko'ra, taqsimlangan tizimlardagi nosozliklarning 50% vaqtinchalik xarakterga ega va takroriy urinishda bartaraf etiladi. Bu Retry Policy ni server arxitekturasini o'zgartirmasdan mobil ilovaning nosozlikka chidamliligini oshirishning eng samarali va arzon usullaridan biriga aylantiradi.
Vaqtinchalik xatolar (retriable) — Retry Policy reaksiya berishi kerak bo'lgan yagona nosozlik turi. Bularga ulanish vaqtining oshib ketishi (SocketTimeoutException), serverning vaqtinchalik mavjud emasligi (HTTP 503, 502) va DNS xatolari kiradi. Doimiy xatolar — HTTP 400, 401, 403, 404 — takrorlashning ma'nosi yo'q, chunki ular tarmoq yoki serverda emas, balki so'rovda muammo borligini ko'rsatadi.
AWS Architecture Blog tadqiqotiga ko'ra, xatolarni retriable va non-retriable ga to'g'ri ajratish Retry Policy ni loyihalashdagi eng muhim qarordir. Idempotent bo'lmagan HTTP 401 so'rovini takrorlash hisob bloklanishiga, HTTP 400 ni takrorlash esa ma'lumotlar dublikatlarining paydo bo'lishiga olib kelishi mumkin. Har doim takrorlanadigan kodlar ro'yxatini aniq konfiguratsiya qiling.
Fixed interval — eng oddiy strategiya: har bir takror bir xil vaqt oralig'idan keyin amalga oshiriladi. Masalan, 2 soniya kechikish bilan ilova so'rovni 2, 2, 2 soniyadan keyin takrorlaydi. Fixed interval amalga oshirishda sodda va bashorat qilinadigan, ammo ommaviy nosozliklarda serverga bir xil yuk hosil qiladi.
Incremental interval — kechikish har bir takror bilan chiziqli ravishda oshadi: birinchi takror 1 soniyadan keyin, ikkinchisi 2, uchinchisi 3 va hokazo. Bu strategiya takrorlanuvchi nosozliklarda serverga tiklanish uchun ko'proq vaqt beradi, ammo bir vaqtda ishlamay qolgan ko'plab mijozlar uchun hali ham bashorat qilinadi.
| Strategiya | Kechikish formulasi | Kumulativ vaqt (3 urinish) | Qo'llanilishi |
|---|---|---|---|
| Fixed | delay = D | 3 × D | Oddiy stsenariylar, mahalliy vaqt oshib ketishlari |
| Incremental | delay = N × D | 6 × D | Yukni bosqichma-bosqich kamaytirish |
| Exponential | delay = D × 2^N | 7 × D | Ommaviy nosozliklar, bulut xizmatlari |
| Exponential + Jitter | delay = random(0, D × 2^N) | o'zgaruvchan | Yuqori yuk, mikroxizmatlar |
Strategiyani tanlash ilovaning xarakteriga bog'liq. Mobil qurilmalarda ma'lumotlarni sinxronlashning fon vazifalari uchun jitter bilan exponential strategiya optimaldir — server va foydalanuvchi qurilmasiga minimal yuk bilan eng yuqori muvaffaqiyat ehtimolini beradi.
Exponential backoff — kechikish har bir urinish bilan ikki baravar oshadigan strategiya. Agar boshlang'ich kechikish 1 soniya bo'lsa, kechikishlar ketma-ketligi 1, 2, 4, 8, 16 soniya bo'ladi. Bu serverga tiklanish uchun eksponensial o'sib boruvchi vaqt beradi.
Jitter — ko'plab mijozlardan sinxron takroriy so'rovlarning oldini oluvchi tasodifiy kechikish og'ishi (thundering herd muammosi). Jittersiz bir xil Retry Policy ga ega minglab mijozlar bir vaqtning o'zida so'rovlarni takrorlab, serverda eng yuqori yukni hosil qiladi. Jitter takrorlarni vaqt bo'yicha tarqatadi.
Kotlin korutinlari asosiy oqimni bloklamasdan jitter bilan exponential backoff ni amalga oshirishga imkon beradi. kotlinx-coroutines dan retry funktsiyasi takrorlash sharti va so'rov tanasi bilan blokni qabul qiladi, kechikishlar va urinishlar sonini avtomatik boshqaradi.
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!!)
}
executeWithRetry funktsiyasi tarmoq chaqiruvi bilan lambdani qabul qiladi va uni exponential backoff va jitter bilan bajaradi. Agar xato takrorlanmaydigan bo'lsa (retriable emas) yoki maksimal urinishlar soni oshib ketgan bo'lsa, funktsiya xato qaytaradi. Kechikish takrorlarning bir xil taqsimlanishi uchun 0.5 dan 1.5 gacha tasodifiy koeffitsientga ko'paytiriladi.
Circuit Breaker — xizmat uzoq vaqt mavjud bo'lmaganda cheksiz takroriy so'rovlarning oldini oluvchi dizayn namunasi. Xatolar soni chegaradan oshganda, Circuit Breaker OPEN holatiga o'tadi va so'rovni bajarmasdan darhol xato qaytaradi, serverga tiklanish uchun vaqt beradi.
Mobil ilovalarda Circuit Breaker rejali texnik xizmat ko'rsatish yoki operator tarmog'i nosozliklari tufayli API mavjud bo'lmaganda ayniqsa foydalidir. Usiz ilova batareya va trafikni cheksiz takroriy urinishlarga sarflab, foydalanuvchi tajribasini yomonlashtiradi va qurilmaning batareya bilan ishlash muddatini qisqartiradi.
Uch holat Circuit Breaker: CLOSED (normal ish, so'rovlar bajariladi), OPEN (rad etish, so'rovlar bloklanadi) va HALF_OPEN (tiklanishni tekshirish uchun sinov so'rovi). OPEN holatida ma'lum vaqtdan so'ng kalit HALF_OPEN ga o'tadi va bitta so'rovni bajaradi — muvaffaqiyatda CLOSED ga qaytadi, muvaffaqiyatsizlikda — OPEN ga.
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
}
}
}
Kotlin da Circuit Breaker amalga oshirilishi xato hisoblagichi va tiklanish taymerini o'z ichiga oladi. protect metodi bloklangan so'rovni bajarishdan oldin joriy holatni tekshiradi va nosozliklarda xato hisoblagichini yangilaydi. failureThreshold chegarasiga erishilgandan so'ng, timeoutMs tugaguncha barcha so'rovlar darhol rad etiladi.
Mobil tarmoqlar Retry Policy ni ayniqsa muhim qiladigan xususiyatlarga ega. Wi-Fi va mobil ma'lumotlar o'rtasida o'tish, metro va tunnellarda signal yo'qotilishi, operator darajasida vaqtinchalik bloklashlar — bu stsenariylarning barchasi takroriy urinishlar bilan muvaffaqiyatli hal qilinadigan so'rov nosozliklariga olib keladi.
Android da Retrofit kutubxonasi va OkHttp Interceptor orqali o'rnatilgan RetryPolicy mexanizmini ta'minlaydi. iOS da masala URLSessionConfiguration va maxsus delegatsiya orqali hal qilinadi. Platformalararo ishlanma uchun Ktor (KMP) sozlanishi strategiyalar bilan o'rnatilgan retry qo'llab-quvvatlashni o'z ichiga oladi.
Combine — Apple ning reaktiv dasturlash freymvorki. Combine dagi retry operatori xato paytida publisher ni belgilangan marta takrorlaydi, ammo takrorlar orasidagi kechikishni sozlashga ruxsat bermaydi. To'liq Retry Policy uchun kechikish bilan catch va flatMap ning maxsus kombinatsiyasi ishlatiladi.
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()
}
}
Combine dagi Publisher uchun retryWithBackoff kengaytmasi hisoblagichni kamaytirish va kechikishni ikki baravar oshirish bilan rekursiv chaqiruv orqali exponential backoff ni amalga oshiradi. delay operatori takrorlar orasida pauza yaratadi, catch esa xatoni ushlab, qayta urinish yoki failure qaytarish haqida qaror qabul qiladi.
Birinchi xato — idempotentlikni tekshirmasdan so'rovlarni takrorlash. Agar server resurs yaratgan bo'lsa, lekin tarmoq nosozligi sababli tasdiqni qaytarmagan bo'lsa, takroriy so'rov dublikat yaratadi. POST so'rovlari uchun har doim sarlavhada idempotent kalitdan (Idempotency-Key) foydalaning yoki retry ni faqat GET, PUT va DELETE uchun qo'llang.
Ikkinchi xato — cheksiz takrorlar (retry forever). Har doim maksimal urinishlar sonini (mobil ilovalar uchun 3-5) va barcha urinishlar uchun umumiy vaqt chegarasini belgilang. Cheksiz takrorlar batareyani zaryadsizlantiradi va serverga parazit yuk hosil qiladi, ayniqsa ma'lumotlar bazasi migratsiyasi yoki API o'zgarishida.
Uchinchi xato — ilovaning kontekstini e'tiborsiz qoldirish. Agar foydalanuvchi ilovani yopgan yoki fon rejimiga o'tgan bo'lsa, faol Retry Policy to'g'ri bekor qilinishi kerak. Ekran yopilganda takrorlarni avtomatik bekor qilish uchun SupervisorScope bilan korutinlardan yoki UI hayot tsikli bilan Combine dan foydalaning.
To'rtinchi xato — takroriy urinishlarni qayd etmaslik. Qayd etmasdan nechta so'rov takrorlanganini, qanday xatolar yuz berganini va Retry Policy ingiz qanchalik samarali ekanligini bilmaysiz. Metrikalar qo'shing: takrorlar soni, takrordan keyingi muvaffaqiyat, kechikishlar taqsimoti. Bu ma'lumotlar strategiyaning optimal parametrlarini muayyan ilova uchun sozlashga yordam beradi.
Tez-tez so'raladigan savollar
Optimal takrorlash soni — ko'pchilik stsenariylar uchun 3-5 urinish. Fon sinxronizatsiyasi uchun 5-7 urinish, interaktiv so'rovlar uchun (masalan, formani yuborish) — 3 dan ko'p emas. Ko'proq takrorlash muvaffaqiyat ehtimolini oshirmaydi, lekin foydalanuvchining batareyasi va trafigini sarflaydi.
Exponential backoff — takroriy urinishlar orasidagi kechikishning ikki baravar oshishi: 1 soniya, 2, 4, 8, 16 va hokazo. Agar server haddan tashqari yuklangan bo'lsa, birinchi takrorlar orasidagi qisqa pauza unga tez javob berishga imkon beradi, har keyingi urinishda o'sib boruvchi pauza esa serverga tiklanish uchun tobora ko'proq vaqt beradi.
Faqat vaqtinchalik xatolarni takrorlang: 408 (Request Timeout), 429 (Too Many Requests), 502 (Bad Gateway), 503 (Service Unavailable), 504 (Gateway Timeout). 4xx xatolari (408 va 429 dan tashqari) mijoz muammolarini ko'rsatadi — ularni takrorlashning ma'nosi yo'q va foydalanuvchi ma'lumotlari uchun xavfli bo'lishi mumkin.
Retry Policy nosozlikda bitta so'rovni takrorlashni boshqaradi. Circuit Breaker xizmat bilan ulanish holatini boshqaradi: xatolar to'planganda zanjirni ochadi (OPEN) va yangi so'rovlarga ruxsat bermaydi. Retry alohida chaqiruv darajasida, Circuit Breaker esa xizmat bilan integratsiya darajasida ishlaydi.
Test uchun Android da NetworkInterceptor (OkHttp) va iOS da URLProtocol (URLSession) yordamida tarmoq nosozliklarini simulyatsiya qiling. Parametrlarni sozlang: xato chastotasi, mavjud bo'lmaslik muddati va javob kodlari. MockWebServer (OkHttp) yoki OHHTTPStubs (iOS) bilan birlik testlari haqiqiy tarmoqsiz takrorlash mantiqini tekshiradi.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.