클라우드

AWS EC2 Nginx 부하 테스트 장애 해결: proxy_pass와 resolver 설정

팬도라 2024. 11. 19. 17:37
반응형

최근에 회사 업무 메신저에 다음과 같은 문제의 해결 방법을 공유하는 글이 올라왔다. 

 

"현재 한 고객사에서 AWS EC2에 Nginx를 배포하여 부하 테스트를 진행 중입니다.
초기에는 문제없이 동작했으나, 테스트가 진행되면서 특정 시점부터 Nginx가 응답하지 않는 현상이 발생하고 있습니다.

ALB(Application Load Balancer) 로그를 확인해 보니 HTTP 460 및 504 상태 코드가 반복적으로 기록되고 있습니다. AWS 지원팀에 문의한 결과, 네트워크에는 문제가 없으며 TCP 연결 문제나 응답 지연에 대한 추가 조사가 필요하다는
답변을 받았습니다. 현재 Nginx의 error.log에는 아래와 같은 오류가 기록되어 있습니다:

an upstream response is buffered to a temporary file
upstream timed out

Nginx 설정 파일에는 별도의 upstream 설정이 포함되어 있지 않으며, 기본 proxy 설정만 사용 중입니다.

이와 관련하여 다음과 같은 점에 대해 조언을 구합니다:

Nginx에서 upstream 설정이 없는 경우에도 ALB와의 연결 안정성을 위해 추가적인 설정이 필요할까요?
Nginx에서 기록된 버퍼링 관련 오류를 완화하기 위해 proxy_buffer 관련 설정을 조정하는 것이 적절할까요?

위 상황에서 원인 분석과 해결 방법에 대해 조언 부탁드립니다."

 

 

 

처음에 이 글을 본 순간에는 리눅스의 FD(File Descriptor), KeepAlive, TCP SYN Queue and Accept Queue Overflow, TIME_WAIT 등 OS나 Nginx에서 발생하는 설정 문제로만 접근을 했었는데, 답변을 보니 이미 널리 공유된 이슈 중에 하나이더라.. 

 

본인은 이번 문제에 전혀 생각해 보지 못하고 헤매었던 부분이라서 본 글을 통해 해당 문제의 대한 문제점과 해결 방법을 정리하고자 한다. 

 

AWS의 ELB(Elastic Load Balancing)을 사용하면 확장 가능한 부하분산 애플리케이션을 쉽게 구축할 수 있다. 

 

이 정도 서비스 설계 및 구축은 클라우드 환경을 조금이라도 다뤄본 사람이라면 쉽게 할 수 있을 것이라 사료되는데, 고객의 상황에 따라 본 아키텍처를 바로 적용하지 않고 Reverse Proxy가 중간에 껴있는 구조를 통해 인프라를 구성할 수도 있다. 

 

상단의 ALB(Application Load Balancer)가 FE 혹은 Reverse Proxy로 유저 트래픽을 전달하면, FE 혹은 Reverse Proxy가 설치된 EC2는 하단의 ALB로 트래픽을 전달해 BE로 트래픽을 최종 전달하는 구조이다. 

 

이러한 아키텍처가 잘못되었다기 보다는 온프렘 환경에서는 Reverse Proxy를 사용하는 부분이 워낙 많다 보니 ELB의 장점과 온프렘 구성의 익숙함 등 여러 장점을 가져갈 수 있는 아키텍처 일수 있는데 이렇게 설정할 경우 놓치지 말아야 할 주의점이 있다. 

 

아래 그림은 이미 10년도 전에 우리와 동일한 문제를 호소하던 질문글이다. 

 

이러한 문제가 왜 발생하는지 이해해 보자! 

AWS ELB를 생성하면 아래 그림과 같은 콘솔 화면을 확인할 수 있다. 

 

AWS ELB를 생성하면 접속을 위한 엔드포인트 DNS를 확인할 수 있다. 우리는 이 DNS 주소를 적절한 설정값으로 입력하게 되면 DNS Lookup 과정을 통해 서버의 적절한 IP로 데이터가 전송된다. 

 

참고로 AWS ELB는 각 AZ당 최소 1개의 IP를 가지게 구성되어 있으므로, Multi AZ 구성이 되어 있을 경우 각 AZ 별 IP가 출력되어야 정상이다. 그렇지 않다면 설정이 잘못된 부분이니 확인해 보도록 하자. 

 

문제의 원인은 바로 여기서 발생하게 되는데, ELB도 AWS의 자원이고 내부적으로 EC2와 같은 형태로 동작하고 있는 리소스이다. 만약 사용자 트래픽이 적다면 ELB의 리소스를 과하게 설정할 필요가 있을까? 혹은 사용자 트래픽이 많다면 ELB는 해당 트래픽을 수용하기 위해서 어떤 일들이 일어날까? 

 

질문으로 돌아가서 고객은 부하 테스트 과정에서 문제가 발생했다고 한다. 트래픽이 늘어났으니 ELB는 늘어나는 트래픽을 수용하기 위해서 Scale-Out이 일어나게 되고, 이로 인해 기존 IP가 변경되는 상황이 발생할 수 있다. 하지만 보통 Nginx에서 Reverse Proxy 구성시 upstream을 선언하거나 proxy_pass에 주소를 지정하면, 설정 파일을 읽는 시점에 해당 DNS에 대한 resolve를 수행하기 때문에 변경된 ELB의 IP 주소로 호출되지 않을 수 있다. 

ELB 도메인의 DNS Query 결과를 보면 TTL 60초로 짧게 설정되어 있는 만큼 동적인 변화에 빠르게 대응할 수 있도록 구성되어 있기 때문에 Nginx Reverse Proxy 설정도 이와 동일하게 resolve를 수행할 수 있도록 변경되어야 한다. 

 

따라서 아래와 같은 답변과 같은 구성을 통해서 설정을 진행해야 동일한 문제를 방지할 수 있다. 

 

 

 

추가적으로 VPC 내부의 DNS 서버는 본인 VPC 대역에 xxx.xxx.xxx.2 이다. 따라서 10.0.0.0/16이라면 10.0.0.2가 내부 DNS 서버로 할당되어 있기 때문에 resolver를 10.0.0.2로 구성하면 된다. 

 

가끔 VPC 내부 네트워크 대역폭을 딱 맞춰서 할당하여 관리하는 경우가 있는데, VPC 생성시 최소 5개는 예약 IP로 빠지게 되고, ELB에서는 확장을 고려 5개 이상의 여유 IP를 요구하기 때문에 (여유 IP가 부족한 경우 ELB 생성 불가) 확장성을 고려하여 구성하도록 하자.