Next.js bilan resilient tizimlar qurish
Zamonaviy veb-ilovalarda yuqori mavjudlik va ishlashni ta'minlash uchun eng yaxshi amaliyotlar.
TL;DR5
- Avval arxitektura, keyin vositalar: resiliens — bu dizayn xususiyati
- stale-while-revalidate'li ISR backend uzilishlarida sahifalarni tirik saqlaydi
- Retry'lar backoff va jitter talab qiladi — circuit breaker kaskadli xatolarni kesadi
- Error boundary'lar xatoni sahifaga emas, buzilgan widget'ga izolyatsiya qiladi
- Fallback UI va oflayn bardoshlilik patch emas, birinchi darajali xususiyatlar

Avval Arxitektura
Next.js ko’pincha zamonaviy veb-ilovalarning umurtqa pog’onasi bo’lib xizmat qiladi. Resiliensni ta’minlash yaxshi arxitektura qarorlari va to’g’ri vositalarning aralashmasini talab qiladi.
Server Components va to’g’ri error boundary’lardan foydalanib, butunlay qulash o’rniga nafis tarzda degrade bo’ladigan o’ta resilient veb-ilovalarni qurish mumkin.
Static Generation vs SSR
Iloji bo’lganda Incremental Static Regeneration (ISR) standart bo’lsin. Bu backend API’laringiz vaqtincha mavjud bo’lmasa ham foydalanuvchilar oxirgi muvaffaqiyatli qurilgan versiyani ko’rishini kafolatlaydi.
Lekin tradeoff haqiqiy: ISR yangilik narxidagi resiliensni beradi. SSR yangilikni backend’ga qattiq bog’liqlik narxidagi beradi.
// app/blog/[slug]/page.tsx
export const revalidate = 300; // 5 daqiqa
export default async function Post({ params }) {
const post = await fetchPost(params.slug); // keshlangan + revalidate qilingan
return <Article post={post} />;
}
O’tgan yili Cloudflare hodisasi paytida origin API’m 40 daqiqa ishdan chiqqanda, y7.hk’dagi barcha ISR sahifalari eski-lekin-haqiqiy HTML’ni taqdim etishda davom etdi. Xuddi shu saytning SSR sahifalari 500 qaytardi. Bu tajriba menga oylik trafikning 4%iga tushdi — va rendering strategiyasi haqidagi fikrimni butunlay o’zgartirdi.
Qoida: 5–60 daqiqa eskirishi mumkin bo’lgan hamma narsa uchun ISR (blog postlari, mahsulot sahifalari, marketing). Eskirganlik mahsulotni sindirgandagina SSR (jonli dashboard’lar, auth holati, real-time ma’lumot).
Error Boundary’lar — Izolyatsiya Bulkhead’lari
Boundary’siz, bitta muvaffaqiyatsiz widget butun sahifani ag’daradi. Boundary bilan har bir bo’lim mustaqil ravishda muvaffaqiyatsiz bo’ladi.
// app/components/Section.tsx
'use client';
import { Component, ReactNode } from 'react';
export class Section extends Component<
{ children: ReactNode; fallback?: ReactNode },
{ hasError: boolean }
> {
state = { hasError: false };
static getDerivedStateFromError() {
return { hasError: true };
}
render() {
if (this.state.hasError) {
return this.props.fallback ?? <div className="opacity-50">Bo'lim mavjud emas</div>;
}
return this.props.children;
}
}
Har bir mustaqil birlikni — sidebar vidjetlari, izoh bo’limlari, analitika dashboard’lari — o’z boundary’siga o’rang. Foydalanuvchi bo’sh ekran o’rniga vidjet bo’lgan joyda kulrang quticha ko’radi.
Men buni Web3 dashboard’ida og’riqli tarzda o’rgandim, bitta RPC timeout butun portfel ko’rinishini ag’dardi. Price ticker atrofidagi bitta boundary sessiyani saqlab qolardi.
Retry’lar Backoff Talab Qiladi
Ko’r-ko’rona retry’lar xatoni kuchaytiradi. Jitter’li eksponensial backoff yukni taqsimlaydi va upstream’ga tiklanish vaqti beradi.
async function fetchWithRetry<T>(
fn: () => Promise<T>,
attempts = 3,
baseDelay = 300
): Promise<T> {
for (let i = 0; i < attempts; i++) {
try {
return await fn();
} catch (err) {
if (i === attempts - 1) throw err;
const jitter = Math.random() * baseDelay;
await new Promise(r => setTimeout(r, baseDelay * 2 ** i + jitter));
}
}
throw new Error('unreachable');
}
Men ikki qoidaga amal qilaman:
- Hech qachon 4xx’ni retry qilmang. 404 retry bilan 200 bo’lmaydi.
- Umumiy kutish vaqtini cheklang. Foydalanuvchi 8+ soniyadan beri spinner’ga qarayotgan bo’lsa, fallback UI ko’rsating va davom etishga ruxsat bering.
Circuit Breaker’lar Kaskadli Xatolarni Kesadi
Retry’lar o’tkinchi xatolarni hal qiladi. Circuit breaker’lar doimiy xatolarni hal qiladi. Backend 30 soniya davomida ishlamayotgan bo’lsa, uni kaltaklashni to’xtating — circuit’ni oching va darhol degrade javoblar taqdim eting.
class Breaker {
private failures = 0;
private openUntil = 0;
constructor(private threshold = 5, private cooldown = 30_000) {}
async call<T>(fn: () => Promise<T>): Promise<T> {
if (Date.now() < this.openUntil) throw new Error('Circuit open');
try {
const result = await fn();
this.failures = 0;
return result;
} catch (e) {
if (++this.failures >= this.threshold) {
this.openUntil = Date.now() + this.cooldown;
}
throw e;
}
}
}
Breaker’siz sekin upstream osilib qolgan Node jarayonlari flotiga aylanadi. Breaker bilan tez xatolar va upstream qaytganda darhol tiklanadigan tizim olasiz.
stale-while-revalidate bilan Edge Caching
Cache-Control sarlavhasi — sizda bor eng arzon resiliens qatlami. stale-while-revalidate edge’ga oxirgi keshlangan nusxani taqdim etishga ruxsat beradi, orqa fonda esa yangi nusxa olinadi.
Cache-Control: public, s-maxage=60, stale-while-revalidate=600
Bu “API ishdan chiqdi — sayt ishdan chiqdi” va “API ishdan chiqdi — ba’zi foydalanuvchilar 10 daqiqagacha eski ma’lumot ko’radi” orasidagi farq.
Fallback UI Xususiyat Sifatida
Fallback’lar biror narsa buzilganda ko’rsatadigan narsangiz emas — ular dizaynning bir qismi. Har bir async bo’limda uch holat bor:
- Yuklanmoqda: yakuniy layout’ga mos skeleton (layout shift yo’q).
- Muvaffaqiyat: haqiqiy kontent.
- Xato: foydalanuvchiga hali ham ishini bajarish imkonini beradigan degrade versiya.
Agar narx vidjetingiz ishlamasa, qizil xato ko’rsatmang — oxirgi keshlangan narxlarni “12 daqiqa oldin yangilangan” nishoni bilan ko’rsating. Izoh tizimi ishlamasa, faqat o’qish uchun thread’ni ko’rsating va input’ni yashiring.
Oflayn Bardoshlilik
Service Worker’lar faqat PWA uchun emas. App shell va oxirgi 5 ta tashrif buyurilgan sahifani keshlaydigan minimal SW g’aroyib mehmonxona wifi’ida va 10 000 metr balandlikda haqiqiy oflayn bardoshlilik beradi — bu mening browsing’imning ahamiyatli qismi.
// sw.ts — statik uchun cache-first, sahifalar uchun network-first
self.addEventListener('fetch', (e) => {
const url = new URL(e.request.url);
if (url.pathname.startsWith('/_next/static/')) {
e.respondWith(caches.match(e.request).then(r => r ?? fetch(e.request)));
}
});
Duch Kelgan Haqiqiy Xatolar
- Cloudflare edge KV uzilishi: KV’ga bog’liq har bir sahifa 500 qaytardi. ISR sahifalari omon qoldi.
- Trafik cho’qqisida upstream CMS meni rate-limit’ladi. Breaker yo’q edi; Next.js qattiq IP ban olguncha CMS’ni kaltakladi. Endi har bir tashqi chaqiruv 30 soniyalik cooldown’li breaker orqali o’tadi.
- WebSocket uzilganda bitta
<PriceTicker>butun dashboard’ni ag’dardi. Boundary qo’shilgach, UI qolgan qismi tirik qoldi, ticker esa jim qayta ulandi.
Resiliens Checklist’i
- 5+ daqiqa eskirishga bardoshli kontent uchun ISR/SSG
- Har bir keshlanadigan marshrutda
stale-while-revalidate - Har bir mustaqil vidjet atrofida error boundary
- Retry’larda eksponensial backoff + jitter; 4xx’ni hech qachon retry qilmang
- Har bir tashqi xizmat chaqiruvida circuit breaker
- Har bir async UI uchun skeleton + fallback + xato holati
- App shell’ni keshlaydigan service worker
- Muhim bo’lmagan xususiyatlar (analitika, tavsiyalar) uchun hujjatlashtirilgan kill-switch
Xulosa
Resiliens — oxirida murvat bilan mahkamlanadigan xususiyat emas. Bu arxitekturaning o’zidir. Har qatlam — rendering, caching, fetching, UI — boshidanoq loyihalangan failure mode’ni oladi. Ularni erta quring, va uzilish bo’lishi mumkin bo’lgan hodisalar hech kim sezmaydigan jim degrade’larga aylanadi.
Blogdan yana
y7.hk'dagi zamonaviy muhandislik maqolasining anatomiyasi
y7 o'qish dvigatelining stress-testi: callout'lar, diff bloklari, KaTeX formulalari, dumaloq avatar video, figure galereyasi, spoilerlar va shrift almashtirgich.
Vaqt zonalari orasida yashash
67 mamlakat va to'rtta asosiy baza chuqur ish, jet lag va hech kim so'ramagan mahsulotlarni yaratish haqida nimani o'rgatadi.
