createConnection vs createPool

jh_leitmotif·2021년 7월 20일
7

이것저것..TIL

목록 보기
2/9

🧐 개요

요즘 건드리고 있는 boiler-plate에는 MySQL과 연동되어 있습니다.

Client <-> (Req, Res) <-> Server <-> (err, rows) <-> MySQL

로그인, 회원가입, 프로필, 게시글, 추천, 찜하기 등등..

위처럼 이것저것이 전부 DB의 테이블들과 연결이 되고있는 가운데

간혹 아래와 같은 오류가 발생할 때가 있었습니다.

Error: Cannot enqueue Query after invoking quit.

이게 무슨 말인고? 한다면, 연결이 끊어진 상태에서 쿼리를 실행하려고 했다는 의미입니다.

쿼리는 비동기식으로 처리되므로 연결 해제 지점을 잘 찾아야하는데..

그 위치를 찾기 귀찮아진 저는 그냥 커넥션 풀 방식으로 바꿔버렸습니다.

DB 연결과 DB Connection Pool 방식을 정리하고, 경우에 따라 참조하기 위해서 이 post에 정리합니다.

맨 밑에 요약 및 참고 링크가 있습니다.


🎯 createConnection()

const mysql = require('mysql');  // A 

const connection = mysql.createConnection({   // 연결 객체 생성, B
	host : '호스트명',
	user: '사용자',
	password : '비밀번호' 
});

connection.connect();  // mysql 연결 
	connection.query("sql 쿼리", function(err, results) {
})   // query 실행

connection.end();

흔히 DB연결을 검색하면 가장 많이 나오는 것 같습니다. 단일 연결 방법입니다.

보통 A, B 부분을 모듈화하여 다른 js 파일에 넣어서 사용하는 편입니다.

1. MySQL 모듈을 불러온다.
2. DB와 연결한다
3. 쿼리를 실행한다
4. 연결을 끊는다.

절차적인 느낌입니다. 또한 Request가 발생할 때마다 객체를 생성하고, 연결을 새로 열었다가 해제해야되는 것은 스트레스의 원인이 될 수 있습니다.

그리고 아마도 역량 부족이겠지만, 기능을 붙이면 붙일 수록 end 지점을 특정하는 것이 어렵다는 것도 느끼고 있습니다.

물론 지금에야 local 환경에서 계속 테스트 중입니다만, 목표는 동시에 다양한 Request를 처리하는 Application이므로 익숙한 것을 걷어내기로 했습니다.


🎯 createPool()

const mysql = require('mysql');

const pool = mysql.createPool({   
    host : "호스트명",
    user : "사용자",
    password : "비밀번호",
    connectionLimit : "연결제한수"
});

pool.getConnection(function(err, connection){  
    if ( err ) 
        throw err;
    else{
        connection.query("sql 쿼리", function(err,results){
            if (err) 
                throw err;
            else 
                console.log(results);
        });
        connection.release() 
    }
});

Node.js + MySQL 에서 Connection Pool을 사용하는 방법입니다.

Connection Pool방식은 미리 연결을 저장해둔 Pool에서 요청이 있을 때 연결을 대여하고 다시 반납받아 저장합니다.

따라서 초기에만 연결 객체가 생성되고, 그 상태를 유지하므로 다시 연결 설정할 필요가 없습니다.

또한 end가 아닌 connection.release()를 사용합니다.
여기서 Connection Pool은 연결을 반납하는 것이지, 해제하지 않는다는 것을 직관적으로 알 수 있습니다.

단일 연결방식과는 다르게 옵션에 connectionLimit가 있습니다.

connectionLimit : Pool이 대여 가능한 연결의 갯수.

만약 연결이 connectionLimit를 꽉 채웠을 때 요청이 있는 경우, 반납이 발생할 때까지 작업을 유보시킵니다.

따라서 현재 구동 중인 서비스의 이용자의 최저, 평균, 최대 접속 통계를 잘 파악하여 연결 숫자를 설정해야됩니다.

각각의 연결은 곧 메모리를 차지하는 것이기에 너무 많이 늘리는 것도 좋지 않고,

너무 적으면 사용자의 환경에 불편함을 초래할 것입니다.


✔ 정리

결국 간단하게 말하면,

먼저 createConnection입니다.

createConnection은 단일 연결 방식으로, 요청이 있을 때마다 연결 객체를 생성했다가, 제거하는 것이 반복됩니다.

따라서 비용, 시간, 연결에 대한 부담이 발생합니다.

createPool, 즉 Connection Pool은 미리 정해진 갯수의 연결을 생성합니다.

그리고 Request가 발생하면 해당 Req에 연결을 할당하고 다시 반납받습니다.

따라서 단일 연결 방식의 비효율적인 연결 설정에 대한 문제가 해소됩니다.

다만 연결 갯수에 따라 메모리를 과하게 차지하거나,

또는 사용자의 대기시간이 증가할 수 있으므로 사용자 추이를 잘 파악하여 연결 제한 갯수를 설정하는 것이 중요합니다.


📋 참고 링크

  1. https://stackoverflow.com/questions/58681908/error-cannot-enqueue-query-after-invoking-quit-in-mysql-with-nodejs
  2. https://stackoverflow.com/questions/26432178/what-is-the-difference-between-mysql-createconnection-and-mysql-createpool-in-no
  3. https://victorydntmd.tistory.com/42
profile
Define the undefined.

1개의 댓글

comment-user-thumbnail
2022년 6월 15일

답글 달기