Node.js 서버의 동시 접속 한도
Node.js 서버의 동시 접속 한도는 기본 설정으로 특정 숫자가 정해져 있지 않지만, 여러 요소에 의해 제한:
-
HTTP 서버 기본 설정:
- Node.js의 HTTP/HTTPS 서버는 기본적으로 연결 수에 엄격한 제한을 두지 않음
- Express 같은 프레임워크는 기본 설정으로 대기열에 5,000개의 요청을 가질 수 있음
-
운영체제 제한:
- 가장 일반적인 제한 요소는 운영체제의 최대 동시 열린 파일(소켓) 수
- Linux에서는 보통
ulimit -n으로 확인 가능하며, 기본값은 1,024 - 이는 서버가 1,024개의 동시 연결을 처리할 수 있음을 의미
-
Node.js 이벤트 루프:
- Node.js는 단일 스레드 이벤트 루프 모델을 사용하므로, 처리 능력은 CPU 작업 부하와 I/O 작업의 효율성에 따라 달라짐
-
하드웨어 리소스:
- 메모리, CPU, 네트워크 대역폭 등 서버의 하드웨어 자원도 제한 요소
프로덕션 환경에서 더 많은 동시 연결 처리 방법
// 서버 생성 시 최대 연결 수 증가 const server = http.createServer(app); server.maxConnections = 10000; // OS 파일 디스크립터 한도 증가 (Linux/Unix) // $ ulimit -n 10000 (터미널에서 실행) // Keep-Alive 타임아웃 설정 server.keepAliveTimeout = 5000; // 5초
실제로는 클러스터 모듈이나 PM2 같은 프로세스 매니저를 사용하여 여러 개의 Node.js 인스턴스를 실행하고, Nginx나 HAProxy 같은 로드 밸런서를 앞단에 두는 것이 일반적
멀티파트 업로드 시스템의 경우, 특히 SSE(Server-Sent Events)를 사용한 진행률 모니터링 때문에 일반적인 HTTP 요청보다 더 많은 리소스를 사용할 수 있으므로, 프로덕션 환경에서는 서버 설정을 적절히 조정하는 것이 중요
현재 구조라면 로드밸런서(LB)만 추가해도 기본적으로 정상 동작할 수 있지만 대용량 트래픽과 멀티파트 업로드를 효율적으로 처리하기 위해서는 몇 가지 추가 설정이 필요
로드밸런서 추가 시 고려사항
-
Connection 수 조정:
- Nginx의 경우
worker_connections값을 조정 (기본값은 보통 512나 1024) - HAProxy의 경우
maxconn값을 조정
- Nginx의 경우
-
세션 관리:
- 멀티파트 업로드의 경우 각 청크가 같은 서버로 가야 함
- 특히
uploadId를 기준으로 동일 사용자의 요청이 동일 서버로 라우팅되어야 함
-
타임아웃 설정:
- 대용량 파일 업로드는 일반 요청보다 오래 걸리므로 타임아웃 설정 확인 필요
- Nginx의 경우
client_body_timeout,proxy_read_timeout등을 조정
Nginx 설정 예시
http {
# 워커 프로세스당 최대 연결 수 증가
worker_connections 10000;
# 요청 본문 크기 제한 증가 (대용량 청크 허용)
client_max_body_size 10M;
# 타임아웃 설정 증가
client_body_timeout 120s;
proxy_connect_timeout 120s;
proxy_send_timeout 120s;
proxy_read_timeout 120s;
# 업로드 ID 기반 세션 일관성 설정
upstream app_servers {
ip_hash; # 또는 더 나은 방법으로 sticky sessions 사용
server app1.example.com:3000;
server app2.example.com:3000;
# 추가 서버...
}
# SSE 관련 설정 (진행률 모니터링용)
server {
# ...
location /api/progress {
proxy_pass http://app_servers;
proxy_http_version 1.1;
proxy_set_header Connection '';
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 24h; # SSE 연결 유지를 위한 긴 타임아웃
}
# 일반 API 엔드포인트
location /api {
proxy_pass http://app_servers;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
}
}
}
HAProxy 설정 예시
global maxconn 10000 defaults timeout connect 10s timeout client 30m # 클라이언트 타임아웃 증가 timeout server 30m # 서버 타임아웃 증가 frontend http-in bind *:80 default_backend app_servers backend app_servers balance source # IP 기반 세션 고정 option http-server-close server app1 app1.example.com:3000 check server app2 app2.example.com:3000 check # 추가 서버...
Node.js 서버에서도 고려할 점
로드밸런서를 추가하더라도 Node.js 서버 자체에서도 다음 설정을 확인해야 함:
// app.js 또는 서버 설정 파일 const server = http.createServer(app); // 연결 시간 제한 증가 server.keepAliveTimeout = 60000; // 60초 server.headersTimeout = 65000; // 65초 // Express나 다른 미들웨어 설정 app.use(express.json()); app.use(express.urlencoded({ extended: true }));
현재 코드에서는 SSE를 사용한 업로드 진행 모니터링이 있으므로, 특히 이 부분이 로드밸런서를 통해 제대로 작동하는지 확인하는 것이 중요. 로드밸런서는 SSE 연결을 장시간 유지할 수 있도록 설정
로드밸런서만 추가해도 기본적인 동작은 가능하지만, 효율적인 운영을 위해서는 로드밸런서와 Node.js 서버 모두에서 연결 수, 타임아웃, 세션 지속성 등의 설정을 적절히 조정해야 함
타임아웃 설정시 일관성이 필요. SSE 연결이 제대로 유지되려면 Node.js 서버의 타임아웃도 로드밸런서의 타임아웃과 일치하거나 그보다 길어야 함
// Node.js 서버 설정 const server = http.createServer(app); // SSE 연결을 위한 긴 타임아웃 설정 server.keepAliveTimeout = 86400000; // 24시간 (밀리초 단위) server.headersTimeout = 86460000; // 약간 더 길게 설정 (24시간 + 1분)
현재 구조에서는 다음과 같은 타임아웃 설정이 일관성 있게 적용되어야 함:
- 로드밸런서(Nginx/HAProxy): 24시간 타임아웃
- Node.js 서버: 24시간 타임아웃
- 업로드 상태 관리: 코드에서
expiresIn: 6 * 60 * 60(6시간)으로 설정되어 있음
특히 uploadStateService에서는 비활성 상태에 대한 타임아웃이 6시간으로 설정되어 있는데, 이 시간도 일관성 있게 조정하는 것이 좋음
리소스 관리 측면에서는 실제 사용 패턴에 따라 이 타임아웃 값을 조정해야 함. 대부분의 업로드가 몇 시간 내에 완료된다면, 24시간보다 짧게 설정하는 것이 리소스 낭비를 줄일 수 있음
댓글 없음:
댓글 쓰기