Connection Pool — nima uchun kerak, qanday sozlanadi
Muammodan boshlaylik
Ma'lumotlar bazasiga har so'rovda yangi ulanish ochilsa nima bo'ladi?
Ulanish ochish — oddiy ish emas. TCP握手, autentifikatsiya, sessiya yaratish — bularning hammasi vaqt oladi. Taxminan 20-100 ms. Sekundiga 1000 so'rov kelsa — sekundiga 1000 ta ulanish ochiladi va yopiladi. Bu resurslarni isrof qiladi va serverni sekinlashtiradi.
Bundan tashqari, PostgreSQL ning o'zi ham ulanishlar sonini cheklaydi — standart bo'yicha 100 ta. 1000 ta ulanish ochishga urinilsa — xato.
Connection Pool nima?
Connection Pool — oldindan ochilgan ulanishlar to'plami. So'rov kelganda yangi ulanish ochilmaydi — pooldan bo'sh ulanish olinadi. So'rov tugagach ulanish yopilmaydi — poolga qaytariladi.
Hayotiy o'xshatma: taksi parki. Har safar yangi mashina sotib olish o'rniga — parkda 10 ta mashina bor. Mijoz kelganda bo'sh mashina beriladi. Mijoz tushgach mashina parkga qaytadi, keyingi mijozga beriladi.
Poolsiz:
So'rov → ulanish och (50ms) → so'rov yubor → ulanish yop
So'rov → ulanish och (50ms) → so'rov yubor → ulanish yop
Pool bilan:
So'rov → pooldan ol (1ms) → so'rov yubor → poolga qaytarish
So'rov → pooldan ol (1ms) → so'rov yubor → poolga qaytarish
Pool sozlamalari
const { Pool } = require('pg');
const pool = new Pool({
host: process.env.DB_HOST,
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
max: 10, // bir vaqtda maksimal ulanishlar
min: 2, // har doim ochiq turuvchi ulanishlar
idleTimeoutMillis: 30000, // 30 soniya bo'sh tursa — yopiladi
connectionTimeoutMillis: 2000, // 2 soniyada ulanib bo'lmasa — xato
});
max — eng muhim sozlama. Bir vaqtda nechta so'rov parallel bajarilishi mumkin. max: 10 bo'lsa — 11-so'rov bo'sh ulanish paydo bo'lguncha kutadi.
Qancha qo'yish kerak? PostgreSQL ning maksimal ulanishlari (standart 100) dan oshmasligi kerak. Bir nechta server bo'lsa — har birining pool hajmi qo'shiladi. Masalan, 3 ta server, har birida max: 20 — jami 60 ta ulanish.
min — server ishga tushganda shu qadar ulanish ochiladi va har doim ochiq turadi. Birinchi so'rov kelganda ulanish ochishni kutmaslik uchun.
idleTimeoutMillis — bo'sh ulanish qancha vaqtdan keyin yopiladi. Trafik kamayganda resurslarni bo'shatish uchun.
connectionTimeoutMillis — ulanish ochishga urinish qancha vaqt kutadi. Bu vaqtda ulanib bo'lmasa — xato chiqaradi.
Pool holati — monitoring
Pool ning hozirgi holatini ko'rish:
app.get('/health', (req, res) => {
res.json({
status: 'ok',
db: {
total: pool.totalCount, // jami ulanishlar
idle: pool.idleCount, // bo'sh ulanishlar
waiting: pool.waitingCount, // kutayotgan so'rovlar
},
});
});
waitingCount ko'p bo'lsa — max ni oshirish kerak yoki so'rovlar sekin bajarilayapti.
Tez-tez uchraydigan xatolar
max ni juda katta qo'yish:
PostgreSQL ning max_connections ini bilib, undan kam qo'yish kerak. Boshqa ilovalar ham ulanadi — limit oshib ketishi mumkin.
Transaction da client.release() unutish:
18-darsda ko'rildi — pool.connect() bilan olingan ulanish release() bilan qaytarilmasa, pool to'lib qoladi. Yangi so'rovlar connectionTimeoutMillis dan keyin xato beradi.
Pool ni har faylda qayta yaratish:
// Xato — har import da yangi pool yaratiladi deb o'ylash
// Aslida Node.js require ni cache qiladi — bir xil fayl bir marta bajariladi
// Shuning uchun module.exports = new Pool() to'g'ri
db.js da bir marta yaratilgan pool — butun loyihada bir xil ob'ekt.
Xulosa
Connection Pool — oldindan ochilgan ulanishlar to'plami. Har so'rovda yangi ulanish ochish o'rniga — pooldan olinadi, qaytariladi.
max — eng muhim sozlama, PostgreSQL limitidan oshmasligi kerak. idleTimeoutMillis — bo'sh ulanishlarni yopadi. connectionTimeoutMillis — ulanish kutish vaqti.
Pool bitta modul sifatida yaratiladi va butun loyihada ishlatiladi.
Keyingi dars
20-dars: JWT — yaratish, tekshirish, access va refresh token