Nginx란? (내부 동작 구조 및 성능에 대하여)

znftm97·2022년 4월 22일
5

Spring & ETC

목록 보기
3/4
post-thumbnail

0. 이 글을 쓰는 이유

회사에서 Nginx 관련 이슈가 생겼고, 이를 해결하기 위한 방법은 알게되었지만, 내부적으로 자세한 이유는 몰랐다.

그냥 그렇구나 하고 넘어갔기 때문에, Nginx가 무엇인지, 왜 등장했는지, 어떻게 동작하는지, 다른 모델과 어떤 차이점이 있는지 등 간단히 알아보자.


1. Web server

Nginx를 살펴보기 전에 Web server가 뭔지 간단히 알아보자.

  • HTTP 프로토콜 기반으로 동작한다.

  • 클라이언트로 부터 요청을 받아 정적 파일을 응답해준다.

  • Web Application Server(WAS)가 너무 많은 역할을 담당하면 트래픽을 감당하지 못할 수 있다. WAS 앞에 Web Server를 둬서 정적 리소스는 Web Server가 처리하도록하고, 애플리케이션 로직같은 동적인 처리를 WAS한테 요청해서 처리한다.

    • 이를 통해 WAS 장애 발생 시 Web Server에서는 별도의 화면 처리가 가능하다.
  • 대표적으로 Apache와 Nginx가 있다.


2. Apache 동작구조

Nginx와의 비교를 위해 Apache가 어떻게 동작하는지 간단히 살펴보자.

  • 클라이언트로부터 요청이 들어올 때 마다 새 프로세스 또는 쓰레드를 생성한다.
    이를 MPM(Multi Process Module)이라 한다.

  • 문제점은 프로세스나 쓰레드 생성 비용은 비싸기 때문에, 요청이 많아질수록 리소스 소모가 심하다는 점이다.


3. Nignx

3-1. Nginx 역할

  1. 위에서 이야기 한 Web Server의 역할을 수행한다.

  2. 여러 WAS들에게 트래픽을 분산시켜주는 로드밸런서 역할을 수행한다.

    • 로드밸런서란 말 그대로 여러 서버에게 트래픽을 분산시켜주는 주체를 의미하고
      이를 로드밸런싱이라고 한다.
  3. 리버스 프록시가 가능하다.

    • 프록시란 대리자라는 뜻을 가지는데, 일반적인 프록시는 클라이언트가 누군지를 숨겨주는 역할을 한다. 즉 서버에선 클라이언트가 누구인지 식별할 수 없다.

    • 리버스 프록시란 반대로 클라이언트에서 서버가 누구인지 식별할 수 없다. 단지 서버를 대리하는 존재만을 알게 된다. 서버가 누군지를 숨겨주는 역할을 한다.

    • 요청하는 클라이언트에서는 서버에 직접 요청하는게 아니라 Nginx 서버에 요청을 하므로 실제 요청을 처리하는 서버는 알 수 없다는 이야기다. 이로 인해 보안성이 향상될 수 있다.

3-2. 기존 Nginx

  • Nginx는 요청을 비동기로 처리한다. 요청당 프로세스 또는 쓰레드를 생성하지 않고 하나의 Worker process가 여러 요청을 처리한다.

  • 위 사진처럼 적은 수의 프로세스, 그리고 프로세스 수는 일정하기 때문에 메모리를 적게 사용하고 이로 인해 Context Switching이 적게 발생한다.

  • MPM 방식인 Apache에 비해 성능히 좋을 수 밖에 없다. 하지만 문제점이 있다. 아래를 보자.

  • 여러 이벤트를 한번에 수신하고, 이를 하나씩 처리하며 필요한 작업을 수행한다.

  • 대부분 이벤트 처리는 매우 빠르게 수행된다.

문제점

  • 문제점은 요청이 Blocking 될 수 있다는 점이다. 예로 아래와 같은 작업들이다.

    • 동기 방식으로 DB에서 응답을 받는 경우

    • 뮤텍스 또는 라이브러리 함수 호출

  • 위와 같은 요청들을 처리하는 동안 Worker porcess는 다른 작업을 수행할 수 없으므로
    이벤트를 처리할 수 없어 성능이 매우 저하된다는 점이다.

  • 그래서 Nginx는 Thread pool 개념을 도입했다.

3-2. Nginx Thread pool

  • Nginx 1.7.11 버전 및 Nginx Plus release 7 부터 Thread pool 방식을 도입했다.
  • worker process가 요청을 TASK QUEUE에 넣으면, 각 요청들을 Thread pool에 있는 Thread들이 수행한다. 수행 결과를 다시 worker process에게 전달한다.

Thread pool 개념을 도입했다고 해서 기본적으로 적용되지 않는다.
1.7.11 버전 이상에서 별도의 설정이 필요하다는 점에 유의하자. (적용 방법은 공식문서에 나와있다.)

3-3. 그래서 Worker process가 뭔데?

  • Master process는 설정파일 read, 포트바인딩과 같은 권한이 필요한 작업을 수행하고
    세 개의 Child process를 만든다.

Cache Loader process

  • 서버 시작 시 실행되고, 디스크의 캐시를 메모리에 올려놓는 역할을 한다.

Cache Manager process

  • 주기적으로 실행되고, 캐시에서 항목을 정리하여 정해진 크기 내에서 유지한다.

Worker process

  • 모든 작업을 수행한다.

  • 네트워크 연결 처리 + 컨텐츠 read + 디스크에 write + upstream 서버와 통신

  • 각 Worker process는 Non-Blocking 방식으로 여러 요청을 처리하여 Context Switching을 최소화 한다.

  • 각 Worker process는 단일 스레드로 동작한다.

3-4. Nginx가 성능이 좋은 이유는?

asynchronous + Non-Blocking

  • 위에서도 계속 이야기 했지만 Nginx는 기본적으로 비동기로 여러 요청을 한번에 처리한다.

  • 동시에 Non-Blocking 형태로 Blocking 되는 현상이 발생하지 않는다.

효율적인 설정 갱신

  • 내가 이해한 바로는, 우리가 Nginx 설정 값을 수정할 때 쓰는 nginx.conf 파일을 수정했을 때 간단하고 효율적으로 작업을 수행한다는 것이다.

  • 어떻게 효율적으로 수행 하는지 간단히 과정을 살펴본다.

    1. 설정 값들을 다시 로드하고, 새로운 Worker porcess를 만들어서 트래픽을 처리하기 시작한다.

    2. 이전 Worker Process는 트래픽을 더이상 받지 않는다. 현재 처리중인 요청을 모두 처리하고 이전 Worker Process는 완전히 종료된다.


4. Nginx 커넥션 부족 에러

  • 회사에서 겪은 Nginx 이슈를 간단히 이야기 해본다.

4-1. 원인

회사에서 운영업무를 맡은 서비스에서, 피크시간이 되면 주문이 누락되는 현상이 발생했다. 원인을 파악하던 중, Nginx 서버에 접속해서 error 로그 파일을 봤는데, 피크시간대에 worker_connections are not enough 에러 메시지가 잔뜩 떠있는걸 확인했다. 원인은 간단했다. 요청이 너무 많아 Worker process가 모든 요청을 처리할 수 없었던 것이다.

4-2. 해결

  • 그러면 nginx.conf 파일에서 Worker process 수를 수정하고 서버를 재시작 하면되겠구나 라는 단순한 생각을 했지만 이로 해결되지 않는다.

  • Nginx 공식 문서를 확인해보면 권장되는 Worker process 수는 CPU 코어와 같은 수를 권장한다. 권장한다고 이야기 한 이유는 더 많은 Worker process를 설정해도 문제는 없다. 하지만 수를 늘린다고 더 많은 요청을 처리하지는 않기 때문이다.

  • Nginx 서버의 Worker process default 값은 1이고, 회사 Nginx 서버의 스펙을 확인해 봤더니 Single core 서버였다. 그래서 결론은 Nginx 서버를 Scale-Up 한 후, Worker process를 늘려야 해결을 할 수 있다.

    • 멀티 또는 쿼드 코어인데 기본설정값을 쓰고 있었다면 Scale-Up 없이 Worker process 수를 늘리면 간단히 해결할수도 있겠다.

5. Nginx 로드밸런싱 환경 구성하기

  • 해당 내용은 이전에 따로 정리했다. 필요하다면 아래 링크를 참고하자.

  • Nginx 도입 자체는 생각보다 쉽다. 그냥 Nginx 설치하고 요청을 전달할 서버의 IP 주소만 설정파일에 명시해주면 잘 동작한다.

  • 하지만 Nginx 서버를 튜닝하는 것이 쉽지 않아 보인다. 만약 필요하다면 튜닝 관련 내용이 잘 정리된 블로그 링크를 참고하자.


참고

profile
자기주도형 개발자

3개의 댓글

comment-user-thumbnail
2022년 7월 12일

잘 읽었어요~
좋은 글 감사합니다~!

1개의 답글
comment-user-thumbnail
2023년 1월 19일

잘 정리된 글이네요

답글 달기