[Node.js] 모듈별 socket 유지처리

최근 개발중인 시스템에서 발생한 외부연결 (redis, mysql) 관련 npm모듈내에서 발생한 socket 오류에 대해 keepAlive 속성에 대해 정리하려고 한다.
keepAlive 속성을 false로 둘 경우 장시간 클라이언트가 idle 상태일때, 원격 측(redis 또는 mysql 서버)에서 소켓이 닫힐때 클라이언트단에서 확인을 할 수가 없어 오류가 발생한다.
지속적으로 ping을 보내거나 idle 상태가 아니라면 괜찮지만, 단일 connection을 연결하여 오랫동안 사용하지 않거나 connection pool 내에서 사용하지 않는 client에서 오류가 발생할 수 있다.

해당 설정이 없더라도 TCP 연결이 정상적으로 유지되고 있을때에는 서버측에서 idle 상태로 인한 중단신호를(wait_timeout, tcp-keepalive) 받을경우에는 해당 오류가 발생하지 않는다.
대부분 운영에서는 쉴세없이 client(redis, mysql 등)이 명령을 날려서 발생할일이 드물지만, 개발중인 local 환경에서 pc가 절전상태이거나 할때 오류 발생가능성이 있다.

참조

TCP Keepalive를 이용한 세션 유지 : https://jihooyim1.gitbooks.io/linuxbasic/content/contents/08.html

linux keep alive 타이머 확인하기

netstat -napo | grep -i 6379 | grep -i est

mysql2

관련에러

Error: This socket has been ended by the other party

처리방법 - client

    // enableKeepAlive 을 true로 추가.
    const pool = mysql.createPool({
        host: 'db',
        user: process.env.MYSQL_USER,
        password: process.env.MYSQL_PASSWORD,
        database: process.env.MYSQL_DATABASE,
        connectionLimit: 2,
        waitForConnections: true,
        queueLimit: 0,
        ... 중략
        enableKeepAlive: true,        // false by default.  !! 이를 true로 추가함.
    });

Redis

관련에러

Error: Redis connection to {HOST ex> https://xxxxxxxxxxx.xxxxx:xxxxx } failed - read ECONNRESET
    at TCP.onStreamRead (internal/stream_base_commons.js:205:27)

처리 - client

    // enableKeepAlive 을 true로 추가.
    const conn = redis.createClient({
        host: 'redisUrl',
        port: 'redisPort',
        ...
        socket_keepalive : true     // true by default !! 레디스는 기본값이 true. 
    })

server측에서 살펴볼 설정

    // file : redis.conf
    timeout: idle 상태 클라이언트 접속 해제 시간 설정, 기본값 0
    tcp-keepalive 300  # 레디스 클라이언트가 응답이 없으면 중단(죽은 클라이언트), 3.21버전부터는 기본값이 300이라고함.

Discussion and feedback