Connection Pool — nima uchun kerak, qanday sozlanadi

~15 daq · Express · Ma'lumotlar Bazasi

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