0

[Java Backend Zero to Hello] BÀI 4.6: CONNECTION POOL

Java Backend Zero to Hello

📚 Bài viết thuộc series Java Backend Zero to Hello 📌 Phần: Phase 4: Database & SQL | Bài 41/86


BÀI 4.6: CONNECTION POOL

Mục tiêu

  • Hiểu vấn đề của Connection thường
  • Sử dụng HikariCP
  • Cấu hình connection pool
  • Best practices

1. VẤN ĐỀ

Mỗi lần tạo Connection mới tốn:

  • TCP handshake
  • Authentication
  • Memory allocation

Với ứng dụng có nhiều request, việc tạo/đóng connection liên tục sẽ:

  • Chậm
  • Tốn tài nguyên
  • Có thể làm database quá tải

2. CONNECTION POOL LÀ GÌ?

Connection Pool duy trì một tập các connection sẵn sàng, tái sử dụng thay vì tạo mới.

┌─────────────────┐
│ Connection Pool │
│ ┌───┐ ┌───┐ ┌───┐│
│ │C1 │ │C2 │ │C3 ││
│ └───┘ └───┘ └───┘│
└─────────────────┘
       ↓   ↓   ↓
   App1 App2 App3

Lợi ích

  • Performance: Tái sử dụng connection
  • Resource management: Giới hạn số connection
  • Reliability: Tự động reconnect

3. HIKARICP

HikariCP là connection pool phổ biến nhất, nhanh và ổn định.

3.1 Dependency

<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>5.1.0</version>
</dependency>

3.2 Cấu hình cơ bản

import com.zaxxer.hikari.*;

HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
config.setUsername("root");
config.setPassword("password");
config.setDriverClassName("com.mysql.cj.jdbc.Driver");

// Pool size
config.setMaximumPoolSize(10);
config.setMinimumIdle(2);

// Timeout
config.setConnectionTimeout(30000);    // 30s
config.setIdleTimeout(600000);         // 10 phút
config.setMaxLifetime(1800000);        // 30 phút

// Pool name
config.setPoolName("MyApp-Pool");

HikariDataSource dataSource = new HikariDataSource(config);

3.3 Sử dụng

try (Connection conn = dataSource.getConnection();
     PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM users")) {

    ResultSet rs = pstmt.executeQuery();
    while (rs.next()) {
        // ...
    }
}

4. CẤU HÌNH NÂNG CAO

4.1 File application.yml (Spring Boot)

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: password
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      maximum-pool-size: 10
      minimum-idle: 2
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000
      pool-name: MyApp-Pool
      connection-test-query: SELECT 1

4.2 Các tham số quan trọng

Tham số Mô tả Mặc định
maximumPoolSize Số connection tối đa 10
minimumIdle Số connection tối thiểu = max
connectionTimeout Thời gian chờ lấy connection 30s
idleTimeout Thời gian connection rảnh bị đóng 10 phút
maxLifetime Tuổi thọ tối đa của connection 30 phút
connectionTestQuery Query test connection -

4.3 Tính toán Pool Size

Công thức đơn giản:

connections = ((core_count * 2) + effective_spindle_count)

Ví dụ: 4 cores, 1 HDD → ~10 connections


5. MONITORING

5.1 JMX

HikariCP tự động expose qua JMX.

5.2 Metrics

HikariPoolMXBean pool = dataSource.getHikariPoolMXBean();
System.out.println("Active: " + pool.getActiveConnections());
System.out.println("Idle: " + pool.getIdleConnections());
System.out.println("Total: " + pool.getTotalConnections());
System.out.println("Waiting: " + pool.getThreadsAwaitingConnection());

5.3 Spring Boot Actuator

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Truy cập: /actuator/metrics/hikaricp.connections.active


6. CÁC POOL KHÁC

Pool Đặc điểm
HikariCP Nhanh nhất, phổ biến nhất
Tomcat JDBC Mặc định trong Tomcat
C3P0 Cũ, ổn định
DBCP Apache Commons
Vibur Nhẹ, async

7. BEST PRACTICES

7.1 ✅ NÊN

// Dùng try-with-resources
try (Connection conn = dataSource.getConnection()) {
    // ...
}

// Đặt pool size phù hợp
config.setMaximumPoolSize(10);  // Không quá lớn

// Test connection trước khi dùng
config.setConnectionTestQuery("SELECT 1");

7.2 ❌ TRÁNH

// Không giữ connection quá lâu
try (Connection conn = dataSource.getConnection()) {
    Thread.sleep(60000);  // ❌
}

// Không tạo nhiều DataSource
HikariDataSource ds1 = new HikariDataSource(config1);  // ❌
HikariDataSource ds2 = new HikariDataSource(config2);  // ❌

8. BÀI TẬP THỰC HÀNH

Bài 1: Cấu hình HikariCP

Tạo class DataSourceConfig với HikariCP.

Bài 2: Benchmark

So sánh performance giữa:

  • Tạo connection mỗi lần
  • Dùng connection pool

Bài 3: Monitoring

Tích hợp Actuator để monitor connection pool.


9. TÓM TẮT

Khái niệm Mô tả
Connection Pool Tái sử dụng connection
HikariCP Pool phổ biến nhất
Pool Size Số connection tối đa
Connection Timeout Thời gian chờ
Max Lifetime Tuổi thọ connection

Bài tiếp theo: 4.7 JPA/Hibernate cơ bản


🧭 Điều Hướng Series

⬅️ Bài trước: BÀI 4.5: JDBC

📋 Lộ trình tổng quan: Xem Toàn Bộ Series

➡️ Bài tiếp theo: BÀI 4.7: JPA/HIBERNATE CƠ BẢN


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí