dh_0e

[DB] 커넥션 풀(Connection pool) 만들기 (in visual studio code with local MySQL DB) 본문

DB/MySQL

[DB] 커넥션 풀(Connection pool) 만들기 (in visual studio code with local MySQL DB)

dh_0e 2024. 7. 3. 21:03

로컬에 MySQL DB 만들기

  • 먼저 MySQL 공식 웹사이트에서 Community Server, Workbench를 OS에 맞게 설치한다
 

MySQL :: MySQL Community Downloads

The world's most popular open source database Contact MySQL  |  Login  |  Register

dev.mysql.com

 

  • 설치가 완료되면 Workbench에 자동으로 생성되었을 MySQL Connection에 비밀번호 입력 후접속해준다
  • 없다면 다음 이미지의 우측 상단 +버튼으로 Connection을 만들어 사용하면 된다.

  • query에 다음과 같은 명령어로 DB를 생성하고 권한을 부여한다

 

1. 'testdb' 라는 데이터베이스를 생성

CREATE DATABASE testdb;

 

2. 'testdb' DB의 모든 테이블(ON testdb.*)의 모든 권한(GRANT ALL PRIVILEGES)을 'testuser'라는 사용자와 'localhost' 호스트가 가지도록 설정

GRANT ALL PRIVILEGES ON testdb.* TO 'testuser'@'localhost';

 

3. MySQL 서버에 변경된 권한 설정을 즉시 적용하는 명령어

FLUSH PRIVILEGES;

 

 

커넥션 풀 생성

  • 위 방법으로 2개의 DB를 만들어 커넥션 풀을 생성해보자
  • .env에 DB에 각 DB의 name, user, password, host, port를 입력해준다
DB1_NAME=GAME_DB
DB1_USER=root
DB1_PASSWORD=1234
DB1_HOST=127.0.0.1
DB1_PORT=3306

DB2_NAME=USER_DB
DB2_USER=root
DB2_PASSWORD=1234
DB2_HOST=127.0.0.1
DB2_PORT=3306

 

  • 이를 중앙 집중식 관리를 위해 env.js로 읽어오면 한 프로젝트에서 .env 파일을 각각 다른 파일에서 읽지 않아도 된다.
// env.js

import dotenv from 'dotenv';

dotenv.config();

export const DB1_NAME = process.env.DB1_NAME || 'database1';
export const DB1_USER = process.env.DB1_USER || 'user1';
export const DB1_PASSWORD = process.env.DB1_PASSWORD || 'password1';
export const DB1_HOST = process.env.DB1_HOST || 'localhost';
export const DB1_PORT = process.env.DB1_PORT || 3306;

export const DB2_NAME = process.env.DB2_NAME || 'database2';
export const DB2_USER = process.env.DB2_USER || 'user2';
export const DB2_PASSWORD = process.env.DB2_PASSWORD || 'password2';
export const DB2_HOST = process.env.DB2_HOST || 'localhost';
export const DB2_PORT = process.env.DB2_PORT || 3306;

 

  • config.js에 이를 객체로 저장시켜 편하게 import 하여 사용하게 만들어준다.
// config.js

import {
  DB1_HOST,
  DB1_NAME,
  DB1_PASSWORD,
  DB1_PORT,
  DB1_USER,
  DB2_HOST,
  DB2_NAME,
  DB2_PASSWORD,
  DB2_PORT,
  DB2_USER,
} from '../constants/env.js';
export const config = {
  databases: {
    GAME_DB: {
      name: DB1_NAME,
      user: DB1_USER,
      password: DB1_PASSWORD,
      host: DB1_HOST,
      port: DB1_PORT,
    },
    USER_DB: {
      name: DB2_NAME,
      user: DB2_USER,
      password: DB2_PASSWORD,
      host: DB2_HOST,
      port: DB2_PORT,
    },
    // 필요한 만큼 추가
  },
};

 

  • 이를 database.js에서 로그를 찍어주며 커넥션 풀을 생성해준다 (연결 확인)
// database.js

import mysql from 'mysql2/promise';
import { config } from '../config/config.js';

const { databases } = config;

const createPool = (dbConfig) => {
  const pool = mysql.createPool({
    host: dbConfig.host,
    port: dbConfig.port,
    user: dbConfig.user,
    password: dbConfig.password,
    database: dbConfig.name,
    waitForConnections: true,
    connectionLimit: 10, // 커넥션 풀에서 최대 연결 수
    queueLimit: 0, // 0일 경우 무제한 대기열
  });

  const originalQuery = pool.query;

  pool.query = (sql, params) => {
    // 쿼리 실행시 로그
    console.log(
      `Executing query: ${sql} ${params ? `, ${JSON.stringify(params)}` : ``
      }`,
    );
    return originalQuery.call(pool, sql, params);
  };

  return pool;
};

// 여러 데이터베이스 커넥션 풀 생성
const pools = {
  GAME_DB: createPool(databases.GAME_DB),
  USER_DB: createPool(databases.USER_DB),
};

export default pools;

 

  • 이를 testConnection.js에서 연결이 됐는지 확인한다.
import pools from '../../db/database.js';

const testDbConnection = async (pool, dbName) => {
  try {
    const [rows] = await pool.query('SELECT 1 + 1 AS solution');
    console.log(`${dbName} 테스트 쿼리 결과: ${rows[0].solution}`);
  } catch (e) {
    console.error(`${dbName} 테스트 쿼리 실행 중 오류 발생: ${e}`);
  }
};

const testAllConnections = async () => {
  await testDbConnection(pools.GAME_DB, 'GAME_DB');
  await testDbConnection(pools.USER_DB, 'USER_DB');
};

export { testAllConnections };

 

  • 메인에서 testAllConnections를 실행하면 다음과 같이 연결이 성공했다고 출력된다.