Written by
Greed.thread
on
on
[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