Load Testing API ด้วย Node.js และ PostgreSQL ด้วย Connection Pool

Jan. 23, 2025 · boychawin

ในบทความนี้ เราจะสร้าง API ด้วย Node.js และ PostgreSQL พร้อมทดสอบประสิทธิภาพด้วย Artillery และใช้ Connection Pool ในการจัดการทรัพยากรฐานข้อมูลเพื่อป้องกันปัญหาอย่างเช่น "too many clients" หรืออื่นๆ


  1. สร้างโปรเจกต์ Node.js

เริ่มต้นสร้างโปรเจกต์และติดตั้งไลบรารีที่จำเป็น:

npm init -y
npm install express pg
npm install -g artillery

  1. การตั้งค่า Database Connection Pool

ใช้ pg.Pool สำหรับการจัดการการเชื่อมต่อกับ PostgreSQL

const { Pool } = require('pg');

const pool = new Pool({
  user: 'user',
  host: 'localhost',
  database: 'my_database',
  password: 'password',
  port: 5432,
  max: 10, // จำกัดจำนวนการเชื่อมต่อใน pool
  idleTimeoutMillis: 30000, // เวลารอจนกว่าการเชื่อมต่อจะถูกปิด
  connectionTimeoutMillis: 30000 // เวลารอการเชื่อมต่อใหม่
});

  1. การพัฒนา API ด้วย Express

สร้าง API ที่ดึงข้อมูลจากฐานข้อมูล

const express = require('express');
const app = express();
const port = 3000;

app.use(express.json());

app.get('/api/v1/resource', async (req, res) => {
  try {
    const result = await pool.query(`
      SELECT o.*, c.name AS customer_name, r.name AS resource_name
      FROM orders o
      JOIN customers c ON o.customer_id = c.id
      JOIN resources r ON o.product_id = r.id
    `)
    res.status(200).json(result.rows);
  } catch (err) {
    if (err.message.includes('too many clients')) {
      res.status(503).send('Service Unavailable: Too many clients');
    } else {
      res.status(500).send('Internal Server Error');
    }
  }
});

app.listen(port, () => console.log(`Server running at http://localhost:${port}`));

  1. สร้างฐานข้อมูล

คำสั่ง SQL สำหรับสร้างและเติมข้อมูล

CREATE DATABASE my_database;

CREATE TABLE customers (
  id SERIAL PRIMARY KEY,
  name VARCHAR(255) NOT NULL
);

CREATE TABLE resources (
  id SERIAL PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  description TEXT
);

CREATE TABLE orders (
  id SERIAL PRIMARY KEY,
  customer_id INT NOT NULL,
  product_id INT NOT NULL,
  quantity INT NOT NULL,
  order_date DATE NOT NULL,
  FOREIGN KEY (customer_id) REFERENCES customers(id),
  FOREIGN KEY (product_id) REFERENCES resources(id)
);

-- เติมข้อมูล
INSERT INTO resources (name, description)
SELECT 'Resource ' || gs, 'Description for Resource ' || gs
FROM generate_series(1, 100000) AS gs;

INSERT INTO customers (name)
SELECT 'Customer ' || gs
FROM generate_series(1, 5000) AS gs;

INSERT INTO orders (customer_id, product_id, quantity, order_date)
SELECT (gs % 5000) + 1, (gs % 100000) + 1, (gs % 10) + 1, CURRENT_DATE - (gs % 30)
FROM generate_series(1, 5000) AS gs;

  1. ทดสอบ API ด้วย Artillery

สร้างไฟล์ test.yml สำหรับกำหนดการทดสอบ

config:
  target: "http://localhost:3000"
  phases:
    - duration: 100
      arrivalRate: 100

scenarios:
  - flow:
      - get:
          url: "/api/v1/resource"

รันการทดสอบด้วยคำสั่ง:

artillery run test.yml

สรุป

การใช้ Connection Pool ช่วยให้ระบบจัดการการเชื่อมต่อกับฐานข้อมูลอย่างมีประสิทธิภาพและลดปัญหาการเชื่อมต่อเกินจำกัด ในบทความนี้ เราได้สร้าง API ด้วย Node.js และ PostgreSQL พร้อมการเติมข้อมูลตัวอย่าง และทดสอบประสิทธิภาพด้วย Artillery การตั้งค่าที่ดีช่วยให้ API สามารถรองรับการใช้งานหนักได้โดยไม่ล่ม

Tags: database