Mundarija (28)
- Bu darsda
- 1. Nega bu kerak?
- 2. Runtime nima
- 2.1 Ta'rif
- 2.2 Edge'da nima bor
- 3. Next 16.4 da Edge: o'lchov va hujjat
- 3.1 Kanon tajribasi: Route Handler
- 3.2 Kanon tajribasi: proxy
- 3.3 Hujjat nima deydi
- 3.4 instrumentation.ts — ikkala runtime uchun
- 4. portfolio dagi Node'ga bog'liq joylar
- 4.1 Jonli: Edge'ga moslik tekshiruvi
- 5. Serverless va DB ulanishlari
- 5.1 Serverless nima
- 5.2 Ulanish nega qimmat
- 5.3 Yechim: pooler
- 5.4 Jonli: pool qanday ishlaydi
- 5.5 Prisma va Drizzle (ko'rsatkich)
- 6. Portfolio qadami: holat yo'q
- 7. Ko'p uchraydigan xatolar
- 8. Mashqlar
- 1-mashq (oson): qaysi runtime?
- 2-mashq (o'rta): kerakli pool hajmi
- 3-mashq (qiyin): navbat statistikasi
- 4-mashq: Portfolio qadami — runtime auditi
- 9. Real ishda
- Xulosa
- Manbalar
Next.js runtime'lar: Node va Edge, serverless va ma'lumotlar bazasi ulanishi
Qisqacha: Next.js server kodi ikki xil muhitda ishlashi mumkin edi. Birinchisi — Node.js runtime (to'liq Node: fayl tizimi,
node:crypto, har qanday npm paket). Ikkinchisi — Edge runtime (faqat veb standart API'lar:fetch,Request,crypto.subtle— tez ishga tushadi, lekin cheklangan). Next 16 da sukut — Node;proxy.tsfaqat Node'da ishlaydi,runtime = "edge"esa hujjatda eskirgan deb belgilangan va Cache Components bilan build xatosi beradi (o'lchangan). Serverless muhitda asosiy muammo boshqa: har instansiya o'z DB ulanishini ochadi va bazaning ulanish chegarasi tez to'ladi — yechim pooling (PgBouncer, Neon pooler yoki HTTP drayver).
Bu darsda
- Runtime nima ekanini va Node bilan Edge qaysi API'larda farq qilishini tushuntira olasiz.
- Next 16.4 da Edge'ning holatini (eskirgan, proxy'da yo'q) va kanon tajribasidagi build xatolarini bilasiz.
- Kodning qaysi qismi faqat Node'da ishlashini (
node:fs,node:crypto) ko'rib aniqlaysiz. - Serverless'da DB ulanishlari nega tugab qolishini hisoblab ko'rsatasiz va pooling bilan yechimni tushuntirasiz.
- Prisma va Drizzle Next'da qayerda turishini bilib olasiz (ular backend qismlarida o'rganiladi).
Oldin bilishingiz kerak: Route Handlers, proxy.ts, Xatolar va instrumentation, Env o'zgaruvchilar.
1. Nega bu kerak?
Next.js haqida maqolalarda "Edge'da ishlating — tezroq bo'ladi" degan maslahatni ko'p uchratasiz. 2022–2024 yillardagi qo'llanmalar export const runtime = "edge" ni deyarli har Route Handler'ga qo'ygan. Aziz ham portfolio dagi /api/qayta-yangila ga shu qatorni qo'shmoqchi bo'ldi.
Kanon buni sinab ko'rdi va build yiqildi. Nega? Va umuman "runtime" nima, nega ular ikkita?
Ikkinchi savol keyinroq, backend qismlarida dolzarb bo'ladi, lekin uning ildizi shu yerda. Next ilovasi ma'lumotlar bazasiga ulansa va Vercel kabi platformada ishlasa, bir kuni "too many connections" xatosi chiqadi. Sababini runtime va serverless tushunchalari bilan birga o'rganamiz.
O'xshatish: oshxona. Node runtime — to'liq jihozlangan restoran oshxonasi: pech, muzlatgich, ombor. Hamma taomni pishirasiz, lekin u bitta joyda. Edge — shahar bo'ylab tarqalgan kichik kiosklar: mijozga juda yaqin, tez ochiladi, lekin faqat choy va somsa. Plov kerak bo'lsa — kiosk qila olmaydi.
2. Runtime nima
2.1 Ta'rif
Runtime (bajarish muhiti) — kodingizni ishga tushiradigan dastur va u bergan imkoniyatlar to'plami. Brauzer — bitta runtime: unda document bor, fs yo'q. Node.js — boshqa runtime: fs bor, document yo'q. JavaScript tili bir xil, atrofdagi "asboblar" farq qiladi.
Next'ning server kodi ikki runtime'dan birida ishlashi mumkin edi:
| Node.js runtime | Edge runtime | |
|---|---|---|
| Asosi | to'liq Node.js | V8 izolyatsiyasi (Node'siz) |
| API'lar | Node + veb standart | faqat veb standart |
node:fs, node:crypto |
bor | yo'q |
eval, new Function |
bor | o'chirilgan |
| Ishga tushish | sekinroq (sovuq start) | juda tez |
| Next 16.4 holati | sukut, hamma joyda | eskirgan |
V8 izolyatsiyasi (isolate) — Chrome'dagi JS dvigateli V8 ning yengil, alohida "xonasi". Node'ning o'zi ham V8 ustida qurilgan, lekin u ustiga fayl tizimi, tarmoq, jarayonlar qo'shadi. Edge esa faqat dvigatelning o'zi va veb API'lar — shuning uchun millisekundlarda ishga tushadi va dunyoning ko'p nuqtasiga tarqatish oson.
2.2 Edge'da nima bor
Next hujjatidagi ro'yxat bo'yicha Edge runtime'da faqat brauzerdagiga o'xshash API'lar: fetch, Request, Response, Headers, FormData, URL, TextEncoder, ReadableStream, crypto (Web Crypto), setTimeout, AbortController. Yo'qlari ham hujjatda aniq yozilgan: Node API'lari (fayl o'qish-yozish), require (faqat ES modullar), eval va new Function, WebAssembly.compile. npm paketlari ishlaydi — agar ular ES modul bo'lsa va Node API'siga tegmasa.
Diqqat: ro'yxatdagilarning ko'pi Node'da ham bor. Node 18 dan beri fetch, Request, crypto.subtle Node'da ham global. Shuning uchun "faqat veb standart" kod ikkala runtime'da ham ishlaydi, "Node API'li" kod esa faqat Node'da.
Tekshirib ko'ring: Kodda
import { readFile } from "node:fs/promises"bor. U qaysi runtime'da ishlaydi?
Javob
Faqat Node.js runtime'da. node: prefiksi — Node'ning ichki moduli (node:test ni Birinchi avtomatik test darsida ko'rgansiz). Edge runtime'da fayl tizimi umuman yo'q: kod u yerga yig'ilmaydi yoki build ogohlantirish beradi.
3. Next 16.4 da Edge: o'lchov va hujjat
3.1 Kanon tajribasi: Route Handler
Kanon portfolio da sinov Route Handler'i yaratdi va unga Edge'ni yoqdi:
// app/api/edge-sinov/route.ts — tajriba, kanonga kirmagan
export const runtime = "edge";
export function GET() {
return Response.json({ runtime: process.env.NEXT_RUNTIME });
}next build (kanon xom chiqishi, ranglar olib tashlangan):
> Build error occurred
Error: Turbopack build failed with 1 error:
./src/app/api/edge-sinov/route.ts:1:14
Error: Route segment config "runtime" is not compatible with `nextConfig.cacheComponents`. Please remove it.Tarjimasi: "Marshrut segmenti sozlamasi runtime Cache Components bilan mos emas. Olib tashlang". portfolio da cacheComponents: true — create-next-app 16.4 uni sukut bo'yicha yoqadi (Loyiha yaratish). generateStaticParams darsida shu oiladagi xatoni ko'rgansiz: revalidate, dynamic, fetchCache — va hatto runtime = "nodejs" ham xuddi shu xabar bilan rad etiladi. Ya'ni Cache Components rejimida runtime sozlamasi umuman yo'q: hamma narsa Node'da.
3.2 Kanon tajribasi: proxy
Ikkinchi urinish — proxy.ts ni Edge'ga o'tkazish:
export const config = {
matcher: ["/loyihalar/:slug"],
runtime: "edge",
};Build:
Error: Next.js can't recognize the exported `config` field in route. Proxy does not support Edge runtime."Proxy Edge runtime'ni qo'llamaydi". Next 15 da middleware.ts sukut bo'yicha Edge'da ishlardi (15.5 dan Node ham tanlanishi mumkin edi) — ko'p eski maqolalar shuni aytadi. Next 16 da u proxy.ts ga aylandi va faqat Node'da ishlaydi (proxy.ts). Rasmiy yangilash hujjati: Edge kerak bo'lsa, hozircha eski middleware.ts qoladi.
3.3 Hujjat nima deydi
Next 16.4 hujjatidagi runtime sahifasi ikkita qiymat beradi: 'nodejs' (sukut) va 'edge' — yonida (deprecated), ya'ni eskirgan. Eslatmada: "Edge Runtime eskirgan. runtime eksportini marshrut fayllaringizdan olib tashlang".
Lekin o'sha 16.4 paketidagi boshqa sahifa — "Edge Runtime" ma'lumotnomasi — boshqacha gapiradi. Ikkalasini aynan keltiramiz:
| Hujjat sahifasi | Asl matn (16.4.0) |
|---|---|
Route Segment Config → runtime |
"The Edge Runtime is deprecated. Remove the runtime export from your route files." |
| Edge Runtime | "The Edge Runtime … used in Proxy." |
proxy.js → Runtime |
"Proxy defaults to using the Node.js runtime. The runtime config option is not available in Proxy files." |
Birinchi va uchinchi qator bir-biriga mos: Edge eskirgan, proxy esa Node'da. Ikkinchi qator ularga zid — "Edge proxy'da ishlatiladi" deydi. Bu, ehtimol, middleware.ts davridan qolgan eskirgan jumla (taxmin, tasdiqlanmagan). Hujjat o'ziga zid bo'lsa — o'lchovga qaraymiz. Kanon o'lchovi aniq: proxy'da Edge build xatosi beradi (yuqoridagi Proxy does not support Edge runtime). Demak kuzatilgan xulq ustun.
Shunday qilib, "hamma narsani Edge'ga" degan maslahat Next 16 da eskirgan. Bu yaxshi saboq: texnologiya tavsiyalari 2–3 yilda o'zgaradi. Maqolani o'qiganda uning sanasi va versiyasiga qarang.
3.4 instrumentation.ts — ikkala runtime uchun
Bitta istisno Xatolar va instrumentation darsida ko'rgansiz: instrumentation.ts hali ham ikkala runtime uchun yig'iladi. Shuning uchun process.version "Edge'da qo'llanmaydi" ogohlantirishini berdi. Next server ishga tushganda logda aniq ko'rinadi:
{"tur":"server-start","runtime":"nodejs"}process.env.NEXT_RUNTIME — kod hozir qaysi runtime'da ishlayotganini bildiradi. portfolio da u hamma joyda "nodejs".
4. portfolio dagi Node'ga bog'liq joylar
Tajribani qo'ying, portfolio ni Edge'ga o'tkazish umuman mumkinmidi? Kod import'lariga qarang:
| Fayl | Import | Nega Node kerak |
|---|---|---|
proxy.ts |
readdir (node:fs/promises) |
Blog postlari ro'yxatini diskdan o'qiydi |
api/qayta-yangila/route.ts |
timingSafeEqual (node:crypto) |
Sirni vaqt bo'yicha xavfsiz solishtirish (revalidatsiya) |
malumot/blog.ts |
readFile |
Markdown fayllarni o'qish |
Uchala joy Node API'siga tayanadi. Edge'da birinchisini fetch bilan, ikkinchisini Web Crypto bilan qayta yozish kerak bo'lardi, uchinchisi esa umuman ishlamasdi — Edge'da disk yo'q. portfolio uchun Edge'ning foydasi ham yo'q: sahifalar statik, TTFB 4–12 ms.
4.1 Jonli: Edge'ga moslik tekshiruvi
Kod faylining import'larini ko'rib, uni Edge'da ishlaydimi-yo'qmi aniqlaydigan kichik tekshiruvchi. Haqiqiy Next buni build vaqtida qiladi — bu uning sodda modeli:
const NODE_ONLY = /^node:|^(fs|path|crypto|child_process)$/;
function edgeReport(file, imports) {
const blocked = imports.filter((name) => NODE_ONLY.test(name));
return blocked.length === 0
? `${file}: Edge'da ishlaydi`
: `${file}: faqat Node (${blocked.join(", ")})`;
}
console.log(edgeReport("proxy.ts", ["node:fs/promises", "next"]));
console.log(edgeReport("route.ts", ["next/cache", "node:crypto"]));
console.log(edgeReport("og.tsx", ["next/og"]));Konsolda:
proxy.ts: faqat Node (node:fs/promises)
route.ts: faqat Node (node:crypto)
og.tsx: Edge'da ishlaydiUchinchi qator — OG rasm fayli: next/og veb standartlarda yozilgan, uni ikkala runtime ham bajaradi. Bu model faqat to'g'ridan import'larni ko'radi; haqiqiy build esa import qilingan paketlarning ichini ham tekshiradi.
5. Serverless va DB ulanishlari
5.1 Serverless nima
Deploy I: Vercel darsida ko'radigan platformalar Next server kodini serverless funksiya sifatida ishga tushiradi. Serverless — "server yo'q" degani emas, "server sizning tashvishingiz emas" degani. Platforma so'rovlar ko'paysa o'zi yangi instansiya (kodingizning ishlab turgan nusxasi) ochadi, kamaysa — yopadi. 10 ta so'rov — 1 instansiya, 10 000 ta — 50 instansiya bo'lishi mumkin.
Bu qulay, lekin bitta muammo yaratadi: har instansiya — alohida jarayon, va har biri ma'lumotlar bazasiga o'z ulanishlarini ochadi.
5.2 Ulanish nega qimmat
Ma'lumotlar bazasi (masalan PostgreSQL — 26-qismda o'rganasiz) har ulanish uchun alohida resurs ajratadi: xotira va jarayon. Shuning uchun ulanishlar soni cheklangan. PostgreSQL'da sozlama max_connections, sukut bo'yicha 100 (PostgreSQL hujjati). Arzon bulut tariflarida undan ham kam bo'lishi mumkin.
Endi hisoblang. Har instansiya o'z ichida 10 ta ulanishli pool (hovuz — tayyor ulanishlar to'plami) ochadi:
const DB_LIMIT = 100;
const POOL_PER_INSTANCE = 10;
for (const instances of [3, 10, 20]) {
const total = instances * POOL_PER_INSTANCE;
const status = total <= DB_LIMIT ? "sig'adi" : "LIMIT OSHDI";
console.log(`${instances} instansiya: ${total} ulanish, ${status}`);
}Konsolda:
3 instansiya: 30 ulanish, sig'adi
10 instansiya: 100 ulanish, sig'adi
20 instansiya: 200 ulanish, LIMIT OSHDIOddiy server'da (VPS) jarayon bitta, pool ham bitta — 10 ulanish doim yetadi. Serverless'da trafik oshgani sayin instansiyalar ko'payadi va ulanishlar soni ko'paytma bilan o'sadi. 101-ulanishda baza rad etadi: PostgreSQL xabari sorry, too many clients already. Sayt aynan eng ko'p odam kirgan paytda yiqiladi.
5.3 Yechim: pooler
Pooler (ulanishlar vositachisi) — ilova bilan baza orasidagi alohida xizmat. Instansiyalar unga yuzlab "yengil" ulanish ochadi, u esa bazaga oz sonli haqiqiy ulanishni qayta-qayta ishlatadi:
flowchart LR
I1["instansiya 1"] --> P["Pooler<br/>PgBouncer"]
I2["instansiya 2"] --> P
I3["instansiya …50"] --> P
P -->|"20 ta haqiqiy ulanish"| D[("PostgreSQL<br/>max 100")]Chap tomonda instansiyalar soni o'zgaradi, o'ng tomonda ulanishlar soni o'zgarmaydi. Bu taksi navbatiga o'xshaydi: yuzlab yo'lovchi bor, mashina esa 20 ta — har biri yo'lovchini olib borib, qaytib keyingisini oladi.
Uchta odatiy yo'l (hujjatlar bo'yicha, kanonda DB yo'q — sinamadik):
| Yo'l | Nima | Qayerda |
|---|---|---|
| PgBouncer | Mashhur ochiq pooler, "transaction" rejimida ulanishni har tranzaksiyadan keyin qaytaradi | O'z server, ko'p bulut xizmatlari ichida |
| Neon pooler | Serverless Postgres xizmati; ulanish satriga -pooler qo'shilsa, PgBouncer orqali o'tadi |
Neon bulutida |
| HTTP drayver | So'rov oddiy HTTP orqali — doimiy ulanish umuman yo'q | Neon serverless drayveri va shunga o'xshashlar |
Transaction rejimidagi pooler'ning narxi bor: bir so'rovda ochilgan sessiya holati (masalan SET buyruqlari, ba'zi tayyorlangan so'rovlar) keyingi so'rovga o'tmaydi. ORM sozlamalarida buning uchun alohida bayroqlar bor — ularni DB qismlarida ko'rasiz.
5.4 Jonli: pool qanday ishlaydi
Pool g'oyasini 2 ta ulanishli kichik model bilan ko'ramiz. 4 ta so'rov keladi, har biri 100 ms davom etadi. Ulanish band bo'lsa, so'rov navbatda kutadi:
function createPool(size) {
let free = size;
const queue = [];
const release = () => {
const next = queue.shift();
if (next) next();
else free += 1;
};
const acquire = () =>
new Promise((resolve) => {
if (free > 0) {
free -= 1;
resolve();
} else queue.push(resolve);
});
return { acquire, release };
}
const pool = createPool(2);
const start = Date.now();
async function query(name) {
await pool.acquire();
const waited = Math.round((Date.now() - start) / 100) * 100;
console.log(`${name}: ulanish oldi (~${waited} ms)`);
await new Promise((r) => setTimeout(r, 100));
pool.release();
}
await Promise.all(["A", "B", "C", "D"].map(query));
console.log("hammasi tugadi, ulanishlar: 2");Konsolda:
A: ulanish oldi (~0 ms)
B: ulanish oldi (~0 ms)
C: ulanish oldi (~100 ms)
D: ulanish oldi (~100 ms)
hammasi tugadi, ulanishlar: 2A va B darhol ulanish oldi, C va D esa 100 ms navbatda turdi. Bazaga hech qachon 2 tadan ortiq ulanish bormadi. Pooler xuddi shuni katta miqyosda qiladi: ilovaga "ulanish cheksiz" ko'rinadi, baza esa chegarasida qoladi. Vaqt 100 ga yaxlitlangan — taymerlar har kompyuterda bir necha millisekundga farq qiladi.
Tekshirib ko'ring:
createPool(2)o'rnigacreatePool(4)bo'lsa, C va D qachon ulanish oladi? Bazaga nechta ulanish ketadi?
Javob
Hammasi darhol (~0 ms) oladi, bazaga 4 ta ulanish ketadi. Tezroq — lekin har instansiya 4 tadan ochsa, 25 instansiyada chegara (100) to'ladi. Pool hajmi — tezlik bilan baza chegarasi orasidagi murosa.
5.5 Prisma va Drizzle (ko'rsatkich)
Next ilovalarida bazaga odatda ORM (Object-Relational Mapping — jadvallar bilan JS obyektlari orqali ishlash vositasi) orqali ulaniladi. Eng ommaboplari — Prisma va Drizzle. Ikkalasining Next uchun hujjatida bitta umumiy maslahat bor. Klientni modul darajasida bir marta yarating va qayta ishlating, har so'rovda yangisini ochmang. Dev rejimida (next dev) fayl o'zgarganda modul qayta yuklanadi, shuning uchun dev'da klient globalThis ga saqlanadi — aks holda har saqlashda yangi pool ochilib, ulanishlar tugaydi.
Server kodi qayerda turadi? Data Access Layer — portfolio dagi malumot/dal.ts. Hozir u fayl va GitHub API'dan o'qiydi, kelajakda shu qatlam bazaga ulanadi. Sahifalar va Server Action'lar o'zgarmaydi — shuning uchun DAL ajratilgan edi. Prisma va Drizzle'ni 27-qismda (ORM, query builder va raw SQL) o'rganasiz.
6. Portfolio qadami: holat yo'q
Bu darsda kod yozilmaydi: kanon to'liq Node runtime'da qoldi, Edge tajribasi build xatosi bilan tugadi (yuqorida). portfolio da DB yo'q — pooling masalasi backend qismlarida.
O'z loyihangizda tekshirish uchun bitta buyruq:
git grep -n "runtime" srcNatijada faqat instrumentation.ts dagi NEXT_RUNTIME bo'lishi kerak. Biror faylda export const runtime qolgan bo'lsa — uni olib tashlang (Next 16 hujjati tavsiyasi).
7. Ko'p uchraydigan xatolar
| Belgi | Sabab | Davosi |
|---|---|---|
Route segment config "runtime" is not compatible with nextConfig.cacheComponents |
Cache Components rejimida runtime eksporti |
Olib tashlang — sukut Node |
Proxy does not support Edge runtime |
proxy.ts da config.runtime: "edge" |
Olib tashlang; proxy faqat Node |
A Node.js API is used … not supported in the Edge Runtime |
instrumentation.ts da Node API |
NEXT_RUNTIME === "nodejs" sharti bilan import |
sorry, too many clients already (Postgres) |
Serverless instansiyalar ko'p ulanish ochdi | Pooler yoki HTTP drayver; pool hajmini kamaytiring |
| Dev'da ulanishlar asta-sekin tugaydi | Har fayl saqlashda yangi DB klienti | Klientni globalThis da saqlang |
| Eski maqoladagi "hamma narsani Edge'ga" | 2022–2024 maslahati | Next 16 hujjati: Edge eskirgan |
8. Mashqlar
Mashqlar kurs/mashqlar/23/39-runtime/ da. Jonli yechimlarni «Ishga tushir» bilan sinang.
1-mashq (oson): qaysi runtime?
- Next 16.4 da sukut runtime —
proxy.tsqaysi runtime'da ishlaydi — faqat- Edge'da yo'q modul:
node:(fayl tizimi) - Bazaga ulanishlarni qayta ishlatadigan vositachi —
- PostgreSQL'da ulanishlar chegarasi sozlamasi —
Yechim
- nodejs —
process.env.NEXT_RUNTIMEham shu qiymatni beradi. - nodejs — Next 16 da proxy'ning runtime'ini sozlab bo'lmaydi.
- fs — Edge'da disk yo'q;
node:crypto,child_processham yo'q. - pooler — masalan PgBouncer; ilova va baza orasida.
- max_connections — sukut bo'yicha 100.
2-mashq (o'rta): kerakli pool hajmi
Funksiya yozing: maxPoolSize(dbLimit, maxInstances, reserve) — har instansiyaga beriladigan eng katta pool hajmi. reserve — admin va migratsiya uchun zaxira ulanishlar. Natija butun son (pastga yaxlitlang, Math.floor) va kamida 1 bo'lsin. Agar 1 ham sig'masa, "pooler kerak" qaytarsin. Sinang: (100, 8, 10), (100, 50, 10), (100, 120, 10).
Yechim
function maxPoolSize(dbLimit, maxInstances, reserve) {
const available = dbLimit - reserve;
const size = Math.floor(available / maxInstances);
return size >= 1 ? size : "pooler kerak";
}
console.log(maxPoolSize(100, 8, 10)); // 11
console.log(maxPoolSize(100, 50, 10)); // 1
console.log(maxPoolSize(100, 120, 10)); // pooler kerak90 ta bo'sh ulanish 8 instansiyaga — 11 tadan (88, ikkitasi ortadi). 50 instansiyada — bittadan, bu allaqachon sekin: har instansiyada so'rovlar navbatga turadi. 120 instansiyada bittadan ham yetmaydi — pool hajmini kamaytirish bilan yechib bo'lmaydi, pooler kerak.
3-mashq (qiyin): navbat statistikasi
«Pool qanday ishlaydi» blokidagi createPool ni kengaytiring: pool har so'rovning navbatda kutgan vaqtini yozib borsin va oxirida stats() — { maxWaitMs, waitedCount } (eng uzoq kutish va kutishga majbur bo'lgan so'rovlar soni) qaytarsin. 6 ta so'rov, pool hajmi 2, har so'rov 100 ms. Kutish vaqtini 100 ga yaxlitlang.
Yechim
function createPool(size) {
let free = size;
const queue = [];
const waits = [];
const acquire = () => {
const asked = Date.now();
return new Promise((resolve) => {
const grant = () => {
waits.push(Date.now() - asked);
resolve();
};
if (free > 0) {
free -= 1;
grant();
} else queue.push(grant);
});
};
const release = () => {
const next = queue.shift();
if (next) next();
else free += 1;
};
const stats = () => ({
maxWaitMs: Math.round(Math.max(...waits) / 100) * 100,
waitedCount: waits.filter((w) => w >= 50).length,
});
return { acquire, release, stats };
}
const pool = createPool(2);
async function query() {
await pool.acquire();
await new Promise((r) => setTimeout(r, 100));
pool.release();
}
await Promise.all(Array.from({ length: 6 }, query));
console.log(pool.stats());Konsolda:
{ maxWaitMs: 200, waitedCount: 4 }6 ta so'rov, 2 ta ulanish: birinchi juftlik kutmaydi, ikkinchisi ~100 ms, uchinchisi ~200 ms kutadi. To'rtta so'rov navbatda turdi. Haqiqiy pool'larda (masalan pg paketi) ham xuddi shunday ko'rsatkichlar bor — waitingCount, totalCount — va production'da ular kuzatiladi: navbat o'sa boshlasa, pool kichik yoki baza sekin. Konsol formati Node'niki; brauzer obyektni {maxWaitMs: 200, waitedCount: 4} ko'rinishida chiqaradi — ma'nosi bir xil.
4-mashq: Portfolio qadami — runtime auditi
O'z portfolio ingizda git grep -n "node:" src buyrug'ini bajaring va har topilgan faylni «portfolio dagi Node'ga bog'liq joylar» jadvaliga o'xshash jadvalga yozing: fayl, import, nega Node kerak. Keyin git grep -n "runtime" src — export const runtime yo'qligini tekshiring. Kod o'zgarmaydi, commit yo'q.
Yechim
Kanon bo'yicha kutilgan natija: proxy.ts (node:fs/promises, node:path), api/qayta-yangila/route.ts (node:crypto), malumot/blog.ts va boshqa fayl o'qiydigan modullar. runtime faqat instrumentation.ts da (process.env.NEXT_RUNTIME). Agar sizda export const runtime = "edge" qolgan bo'lsa (masalan eski qo'llanmadan ko'chirilgan OG rasm faylida) — olib tashlang: Cache Components bilan build baribir o'tmaydi.
9. Real ishda
- Edge tarixi — 2022–2024 yillarda "Edge hamma narsani tezlashtiradi" degan to'lqin bo'ldi. Amalda ko'p jamoalar Node'ga qaytdi: baza odatda bitta mintaqada, Edge funksiya foydalanuvchiga yaqin, lekin bazadan uzoq — har so'rov okean osha boradi. Next 16 hujjatidagi "eskirgan" belgisi shu tajribaning natijasi.
- Cloudflare Workers — Edge'ga o'xshash muhit hali ham keng ishlatiladi; Next'ni u yerda ishga tushirish uchun OpenNext kabi adapterlar bor (Deploy darslarida ko'rsatkich).
- "Too many connections" — serverless'ga o'tgan jamoalarning eng mashhur xatosi. Intervyuda: "Serverless'da Postgres bilan qanday muammo bor?" — javob: instansiyalar × pool >
max_connections, yechim — pooler. - Data Access Layer — bazani almashtirish (fayldan Postgres'ga) faqat bitta qatlamni o'zgartiradi; bu arxitektura savoli intervyularda ham uchraydi.
Xulosa
- Runtime — kodni bajaradigan muhit; Node to'liq (fayl,
node:crypto), Edge faqat veb standart API'lar bilan. - Next 16.4: sukut Node;
proxy.tsfaqat Node;runtime = "edge"eskirgan va Cache Components bilan build xatosi (o'lchandi). portfolioNode API'lariga tayanadi (readdir,timingSafeEqual) — Edge'ga o'tkazishning foydasi ham, imkoni ham yo'q.- Serverless'da instansiyalar × pool hajmi baza chegarasidan oshadi —
too many clients. - Yechim — pooler (PgBouncer, Neon) yoki HTTP drayver; ORM klienti bitta, dev'da
globalThisda.
Keyingi dars: Deploy I: Vercel — next build + next start lokal production, Vercel'ga joylash oqimi, preview va env muhitlari.
Manbalar
- Next.js hujjati — Edge Runtime (API ro'yxati, cheklovlar; "used in Proxy" jumlasi): https://nextjs.org/docs/app/api-reference/edge (16.4.0 bilan kelgan nusxa
01-app/03-api-reference/07-edge.md, 2026-10-21 da o'qildi) - Next.js hujjati — Route Segment Config
runtime('edge'— deprecated): https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config/runtime - Next.js hujjati —
proxy.js(Runtime bo'limi) va Upgrading to version 16 (middleware→proxy): https://nextjs.org/docs/app/api-reference/file-conventions/proxy - PostgreSQL hujjati —
max_connections: https://www.postgresql.org/docs/current/runtime-config-connection.html - PgBouncer hujjati — pool rejimlari: https://www.pgbouncer.org/features.html
- Neon hujjati — Connection pooling: https://neon.com/docs/connect/connection-pooling
- Kanon:
portfoliov2 tajribasi — Edge build xatolari (Route Handler va proxy), Node API'li fayllar; pool modeli — o'quv modeli, DB bilan sinalmagan.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!