programing

Node/Express 응용 프로그램에서 MySQL 연결이 누출되는 이유는 무엇입니까?

oldcodes 2023. 6. 18. 16:19
반응형

Node/Express 응용 프로그램에서 MySQL 연결이 누출되는 이유는 무엇입니까?

아래 코드가 요청을 받을 때마다 새 연결/풀을 여는 이유를 이해할 수 없습니다.결과적으로 이 코드는 수백 개의 열린 연결을 생성하고 결국 1시간 이내에 충돌합니다.

하단에 오류 메시지를 추가했습니다.

db.js

function connection() {
    try {
        const mysql = require('mysql2');
        const config = require('../config');

        const pool = mysql.createPool(config.db);
        const promisePool = pool.promise();

        return promisePool;
    } catch (error) {
        return console.log(`Could not connect - ${error}`);
    }
}

const pool = connection();

module.exports = {
    connection: async () => pool.getConnection(),
    execute: (...params) => pool.execute(...params)
};

config.js

const config = {
    db: {
        host: process.env.DB_HOST,
        port: process.env.DB_PORT,
        user: process.env.DB_USER,
        password: process.env.DB_PASSWORD,
        database: process.env.DB_NAME,
        connectionLimit: 10,
        waitForConnections: true,
        queueLimit: 0
    },
    listPerPage: 10,
};

module.exports = config;

이제 데이터베이스를 조회하는 파일입니다.

const db = require('./db');

async function getByName(name) {
    const sql = `SELECT name, pubkey FROM name WHERE name="${name}"`;

    const [result] = await db.execute(sql);

    if (result && result.length == 1) {
        var resp = JSON.parse(`{
            "names": {
                "${result[0].name}": "${result[0].pubkey}"
            }
        }`);

        return resp;
    } else {
        return {};
    }
}

도와주셔서 감사합니다!

업데이트 1 =======

전체 코드는 https://github.com/sebastiansieber/nostr-nip05-verification 에서 확인할 수 있습니다.

(작은 저장소이므로 걱정하지 마십시오. 위의 파일을 쉽게 찾을 수 있습니다.)

업데이트 2 =======

너무 많은 연결로 인해 응용 프로그램이 종료될 때 받는 오류 메시지입니다.

Error: Too many connections
    at Packet.asError (/usr/src/app/node_modules/mysql2/lib/packets/packet.js:728:17)
    at ClientHandshake.execute (/usr/src/app/node_modules/mysql2/lib/commands/command.js:29:26)
    at PoolConnection.handlePacket (/usr/src/app/node_modules/mysql2/lib/connection.js:487:32)
    at PacketParser.onPacket (/usr/src/app/node_modules/mysql2/lib/connection.js:94:12)
    at PacketParser.executeStart (/usr/src/app/node_modules/mysql2/lib/packet_parser.js:75:16)
    at Socket.<anonymous> (/usr/src/app/node_modules/mysql2/lib/connection.js:101:25)
    at Socket.emit (node:events:394:28)
    at addChunk (node:internal/streams/readable:312:12)
    at readableAddChunk (node:internal/streams/readable:287:9)
    at Socket.Readable.push (node:internal/streams/readable:226:10) {
  code: 'ER_CON_COUNT_ERROR',
  errno: 1040,
  sqlState: '',
  sqlMessage: 'Too many connections',

업데이트 3 =======

요청에 따라 프로세스 목록이 어떻게 표시되는지 확인하십시오.

enter image description here

문제는 코드 문제가 아니라 잘못 구성된 MariaDB였습니다.

다음 질문/답변은 올바른 방향으로 나를 가리켰습니다."Sleep" 항목으로 채워진 MySql Proccess 목록이 "Too many connections"로 이어집니까?

그래서 저는 SQL 명령을 실행하여 무엇이wait_timeout다음과 같습니다.

SQL Output

보다시피 시간 제한은28800그래서 그것은 그것들을 닫기 전에 그것들을 28800초 동안 잠을 자도록 유지할 것입니다.연결이 닫히기 전에 데이터베이스가 다음 한계에 도달합니다.max_connections500을 초과하면 응용 프로그램이 충돌합니다.

솔루션은 다음을 변경하여 MariaDB의 구성을 변경하는 것이었습니다.wait_timeout=120120초 후에 절전 연결이 닫힙니다.

이것이 다른 사람에게 도움이 되기를 바랍니다.

저는 당신의 스크립트를 로컬로 실행하고 요청을 퍼부었습니다. 정상적으로 실행되었고, 연결 제한을 준수했으며, 10개 이상의 연결을 생성한 적이 없습니다.

이 시점에서, 저는 여러분이 MySQL 유출에 직면한 것이 아니라, 제가 "실행" 유출이라고 부르는 것에 직면해 있다고 확신합니다. 제가 관찰한 바에 따르면, 여러분은 프로젝트 프로세스를 여러 번 퍼뜨리고 있거나 연결이 다른 곳에서 온 것입니다.

스크립트를 어떻게 실행하고 있습니까?도커를 사용하고 있습니까?그렇다면 모든 컨테이너를 중지하고 컴퓨터에서 직접 스크립트를 실행합니다(사용).node문제가 계속 발생하는지 확인합니다.

이 작업을 수행하기 전에 nodejs 응용 프로그램의 단일 인스턴스만 실행 중인지 확인을 참조하십시오.

코드가 새지 않았으므로 다른 원인이 있을 수 있습니다.

만약 당신이 이 URL을 따른다면, 당신은 모든 SLEEP' 프로세스를 가질 수 없을 것입니다. - http://www.vogella.com/tutorials/MySQLJava/article.html
연결을 적시에 종료할 수 있습니다.이렇게 하면 리소스가 해제되고 메모리 누수가 발생하는 것을 방지할 수 있습니다.

언급URL : https://stackoverflow.com/questions/75216691/why-is-my-node-express-application-leaking-mysql-connections

반응형