NGINX와 Node.js의 Express앱 성능 테스트 중 HTTP STATUS 502
와 ETIMEDOUT
에러를 만나게 되었습니다.
- 502 BAD GATEWAY : upstream으로 부터 유효하지 않은 응답을 받으면 발생
- ETIMEDOUT : socket으로 서버와 연결 시도 중 제한시간 안에 연결이 진행되지 않으면 발생
시나리오 완료도 못하고 502에러...
누락된 요청 : 265(ETIMEDOUT) * 스레드 100개 = 26500 (약14%)
502 BAD REQUEST : 40772 (약22%)
👎 67272/180000 (약36%)
All virtual users finished
Summary report @ 14:28:08(+0900) 2021-06-30
Scenarios launched: 1800
Scenarios completed: 1535
Requests completed: 153500
Mean response/sec: 638.11
Response time (msec):
min: 4
max: 9987
median: 527
p95: 1407
p99: 2201
Scenario counts:
0: 1800 (100%)
Codes:
200: 112728
502: 40772
Errors:
ETIMEDOUT: 265
upstream was {
server express:3000;
}
NGINX에서 위 설정 처럼 upstream에 별도의 설정을 하지 않는다면 같은 사용자의 요청에 매번 NGINX와 upstream사이에 TCP Handshake로 세션을 수립하고 Response 후 소켓을 끊게 됩니다.
TPS가 높은 서버에서는 아래와 같은 문제가 발생할 수 있습니다.
TCP로 연결이 설정되면 local 및 remote host 모두 소켓이 생성됩니다. local 포트는 운영체제에서 사용할 수 있는 범위 내에서 무작위로 선택되는데 생성할 수 있는 범위 이상 소켓을 생성하면 오류가 발생합니다.
그렇다면 현재 운영체제의 최대 소켓 생성 개수는 몇 개 일까요? linux의 경우 아래 명령어를 통해 확인할 수 있습니다.
stsctl -a | grep somaxconn
...
net.core.somaxconn = 1024
...
upstream was {
server express:3000;
keepalive 64;
}
200 OK : 180000 (100%)
All virtual users finished
Summary report @ 14:34:36(+0900) 2021-06-30
Scenarios launched: 1800
Scenarios completed: 1800
Requests completed: 180000
Mean response/sec: 988.96
Response time (msec):
min: 2
max: 769
median: 16
p95: 72
p99: 133
Scenario counts:
0: 1800 (100%)
Codes:
200: 180000
Artillery에서
-o [filepath]
옵션으로 결과를 json으로 저장할 수 있는데artillery report [filepath]
명령을 통해 예쁜 차트를 가진 html파일로 변환할 수 있습니다.
RPS(TPS)는 상승, Latency(p95)는 확연히 줄어들고 HTTP STATUS 502
와 ETIMEDOUT
에러가 사라진 것을 볼 수 있습니다.
upstream의 keepalive는 일반적이라면 16~64를 설정하지만 Traffic이 몰리거나 사용자가 지속적으로 자주 요청하는 웹서버의 경우 1000이상 설정한다고도 합니다.
높은 만큼 리소스 자원을 많이 할애하니 성능 테스트를 통해 적절한 keepalive를 찾는 것이 중요하다고 생각합니다.
잘못된 내용, 피드백은 환영입니다!