[TypeScript-Express]MySQL2 Connection Pool 사용하기

Oneik·2024년 3월 25일
1

개요

이전에는 JavaScript를 이용하여 Express 기반의 백엔드 서버를 개발하였다. 이번 프로젝트에서는 TypeScript를 도입하여 서버를 만들어보려한다. 그 중 데이터베이스와의 연결을 최적화하기 위해 커넥션 풀(Connection Pool)을 사용한 경험에 대해 공유하려 한다.

커넥션 풀(Connection Pool)이란?

사용자의 요청마다 데이터베이스와의 연결을 새로 생성하고, 작업 완료 후 연결을 해제하는 것은 비효율적이라고 생각했다. 이러한 문제를 해결하기 위해 커넥션 풀(Connection Pool)이라는 기능을 사용했다.

커넥션 풀이란, 데이터베이스와의 연결을 미리 여러 개 생성해두고, 필요할 때마다 이를 재사용하는 방식을 말한다. 즉, 요청이 들어올 때마다 연결을 생성하는 대신, 미리 준비된 연결을 가져다 사용하고 작업이 끝나면 다시 Pool에 반환하는 것이다.

이러한 커넥션 풀을 이용하여 이전의 연결을 생성하는 과정을 생략할 수 있게 되었다.

커넥션 풀 사용하기

// mariadb.ts

import { Pool, createPool } from "mysql2/promise";
import { MARIADB_DATABASE, MARIADB_HOST, MARIADB_PASSWORD, MARIADB_USER } from "../settings";

const pool: Pool = createPool({
  host: MARIADB_HOST,
  user: MARIADB_USER,
  password: MARIADB_PASSWORD,
  database: MARIADB_DATABASE,
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0,
});

export default pool;

createPool 메서드를 사용하여 커넥션 풀을 생성한 하였고, 외부에서 사용할 수 있도록 export 해주었다.

위처럼 생성한 커넥션을 가져다 사용하기 위해서는 getConnection()메서드를 이용해야했다.

모든 데이터베이스와 연결하는 곳에서 매번 getConnection메서드를 사용해야한다면, 이것 또한 중복된 코드를 생성하고, 비효율적이라고 생각했다. 하나의 Middleware에서 커넥션을 빌려주고 반환한다면 더 효과적이라 생각했다.

poolConnectionMiddleware

// poolConnection.middleware.ts

import { Request, Response, NextFunction } from "express";
import pool from "../utils/mariadb";

export const poolConnection = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const connection = await pool.getConnection();
    req.poolConnection = connection;

    res.on("finish", () => {
      if (req.poolConnection) req.poolConnection.release();
    });

    next();
  } catch (error) {
    next(error);
  }
};

애플리케이션의 모든 데이터베이스 요청에서 커넥션 풀을 사용하기 위해, 커넥션을 관리하는 미들웨어를 구현했다.이 미들웨어에서는 풀에서 커넥션을 가져와 Request 객체에 담아줬다.

그 후, HTTP의 모든 요청이 끝나면 커넥션을 반납하도록 설정하였다.

타입 확장

// express.d.ts
import { PoolConnection } from "mysql2/promise";

declare global {
  namespace Express {
    interface Request {
      poolConnection?: PoolConnection;
    }
  }
}

그러나 위의 방식에도 문제점이 있었는데, TypeScript를 도입함으로써, Request 객체에 특정 요소를 추가하기 위해서는 타입을 확장할 필요가 있었다.

기존의 Express namespace 아래에 존재하던 Request 인터페이스에 poolConnection이 존재할 수 있도록 추가함으로써, 커넥션 풀을 관리하는 미들웨어에서 Request 객체에 connection을 할당할 수 있게 되었다.

profile
초보 개발자의 블로그입니다

0개의 댓글

관련 채용 정보