ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [NGINX] Nginx에 대해서
    Backend 2023. 12. 28. 14:46

    Nginx는 높은 성능과 안정성, 그리고 현재 가장 많이 사용되고 있는 웹 서버이다. Apache같은 웹 서버와 비교하면 더 빠르고 가볍, 대규모 어플리케이션에 적합하다는 장점이 있다. 웹서버에 대해 알아보고, Apache와 비교하며 Nginx에 대해 알아보자!

     

    웹 서버란?

    웹 서비스의 구성요소로는 클라이언트, 웹서버, WAS, DB를 들 수 있다.

     

    클라이언트

    • 서비스를 이용하기 위해 네트워크를 통해 요청을 보내는 주체
    • 웹 개발 영역에서 클라이언트는 보통 웹 브라우저

     

    웹 서버

    • 클라이언트 요청에 따라 정적 파일(HTML, CSS, JS, 이미지 등)을 응답하여 제공하는 소프트웨어
    • HTTP 프로토콜을 사용하여 클라이언트와 통신
    • Nginx, Apache, Node.js 등

     

    WAS(Web Application Server)

    • 클라이언트 요청에 대해 동적인 처리를 담당하는 서버
    • 웹 서버와 달리 애플리케이션 로직을 실행할 수 있음
    • Node.js, Apache Tomcat, WebLogic 등

     

    DB

    • 정보를 체계적으로 저장, 관리하고 검색할 수 있는 시스템
    • RDBMS(MySQL, Oracle RDBMS 등), NoSQL(MongoDB, Redis 등)

     

    웹 서비스는 클라이언트 → 웹 서버  → WAS → DB 순으로 요청이 되고 DB → WAS → 웹 서버 → 클라이언트 순으로 응답된다.

     

     

    웹 서버를 사용하는 이유?

    1. WAS 부담을 줄여주기 위함

    동적 작업을 처리하는 것만으로도 작업량이 많기 때문에 정적인 파일을 클라이언트에게 전달하는 역할을 웹 서버에 위임하여 WAS 작업 부담을 줄인다.

     

    2. 보안 기능 제공

    웹 서버는 보안 기능을 제공하여 웹 페이지에 대한 접근을 제어할 수 있다. 또한 데이터 암호화, 액세스 제어, 웹 방화벽 등 보안 기능을 제공한다.

     

    3. 높은 성능

    웹 서버는 대부분 비동기 처리 방식을 사용하여 높은 성능을 제공한다. Nginx는 이벤트 기반, 멀티 프로세싱, 스레드 풀 등의 기술을 사용하여 다수의 클라이언트 요청을 동시에 처리할 수 있다.

     

     

     

     

    Nginx

    Nginx는 동시 접속(다중 커넥션) 처리에 특화된 웹 서버이다.  Nginx는 웹 서버로써

    1. 정적 파일을 웹 브라우저에 전송하는 HTTP 서버의 역할과
    2. 요청을 WAS에 전달하는 리버스 프록시 서버 역할을 한다.

     

     

    Nginx의 역사

    Apache의 등장

    Apache다양한 모듈을 안정적으로 추가할 수 있는 웹 서버로 등장했다. 웹 서버는 많은 사용자가 접속하기 때문에 동시 접속에 대한 처리를 해야한다. 아파치는 unix계열의 OS가 네트워크 커넥션을 생성하는 방식과 유사하게 유저 요청이 들어오면 프로세스를 할당해 처리하도록 구현했다. 프로세스를 생성하는 비용은 부하가 상당하기 때문에 프로세스를 미리 생성해서 할당하는 PREFORK 방식을 활용했다.

    Process Driven 방식을 사용하여 클라이언트 요청 하나에 프로세스 하나를 할당한다. 요청이 들어오면 PREFORK 과정을 통해 생성해놓은 프로세스를 할당해 요청을 처리하고, 만약 PREFORK로 만들어놓은 프로세스가 이미 누군가의 요청을 처리하고 있다면 새로운 프로세스를 만들어 처리한다.

    이 방식은 다양한 모듈을 만들어 동적으로 처리하기 좋았다. WAS의 동적 처리를 모듈로 구현해두면 아파치가 이 로직을 포함해 요청을 처리한다.

     

     

    C10K 문제

    트래픽이 많아지면서 아파치는 클라이언트의 커넥션을 처리할 프로세스를 새롭게 생성해주지 못하는 문제가 생겼다. 커넥션 10000개를 동시에 처리하기 어렵다는 뜻에서 이 문제를 C10K 문제로 부른다.

     

    커넥션 10000개를 유지한다는 것이 유저의 요청을 10000개까지 받을 수 있다는 뜻이 아니다. 하나의 클라이언트가 동일 커넥션에 여러 요청을 보낼 수도 있고, 서버가 응답을 보낸다고 해도 바로 커넥션이 끊기지 않기 때문이다.(Keep-Alive설정)

     

    C10K는 CPU 성능의 문제보다는 아파치 내부 구조 문제때문이다. 모듈을 쉽게 얹을 수 있기 때문에 서버 프로세스가 무거워지고, 프로세스를 커넥션만큼 생성하니 메모리가 버티지 못하며, 수많은 프로세스가 Context Switching 하는 비용도 있었다. 따라서 다중 요청을 처리하기에 부적합한 구조였다.

     

    이러한 C10K 문제를 근본적인 구조를 바꾸어 해결한 Nginx가 등장하게 된다.

     

     

     

     

    Nginx 구조

    Nginx는 아파치 앞 단에 두어 아파치가 받을 커넥션을 줄여줄 목적으로 만들어졌다. Nginx는 웹 서버로써 HTML, CSS, JS, 이미지 파일 등의 정적 파일은 직접 반환하고, 동적으로 처리할 요청만 아파치로 보내 커넥션을 줄일 수 있다. 요청은 Nginx에 Keep-Alive로 연결되어 있지만 아파치로 보낼 때 별도 요청을 받아 해당 커넥션을 유지시키지 않을 수 있다.

     

    Nginx는 다중 커넥션이 연결되어 있지만 아파치에서 발생한 프로세스 문제를 해결한다. 어떻게 해결할 수 있을까?

     

     

    마스터 프로세스, 워커 프로세스

    Nginx는 요청이 많이 들어와도 프로세스를 늘리지 않는다. 그렇기 때문에 프로세스 문제를 해결할 수 있다.

    Nginx는 설정 파일을 읽고 유효성을 검사하는 Master Process와 요청을 처리하는 Worker Process로 구성된다. Worker Process의 개수는 설정 파일에 정의되고 정의된 프로세스 개수와 사용가능한 CPU 코어 숫자에 맞게 자동으로 조정된다.

    그럼 제한된 프로세스에서 다중 커넥션 요청을 어떻게 처리할 수 있을까? Nginx는 Event-Driven 방식을 통해 프로세스 숫자가 정해져 있음에도 다중 커넥션 요청을 처리할 수 있다.

     

     

    Event-Driven

    Event-Driven에서 connection의 연결과 종료, 요청을 처리하는 것을 이벤트라고 한다. 이벤트는 working queue에 순차적으로 담겨 worker process가 처리하도록 한다. worker process는 하나의 스레드로 이벤트를 처리한다. 쉬지않고 이벤트를 처리하여 서버 자원을 효율적으로 사용한다. (요청이 없을 때 keep-alive 상황에서 메모리만 쓰던 아파치와의 차이점!)

    Apache 스레드 방식 VS Nginx Event-Driven 방식

     

     

    Non-Blocking 방식

    working queue의 이벤트 중 disk I/O처럼 시간이 오래걸리는 작업이 들어온다면, 해당 작업이 처리되는 동안 working queue의 요청들은 대기해야하는데 이를 Blocking이라고 한다. Nginx에서는 Non-Blocking 방식으로써 이를 해결한다.

     

    Evnet-Driven 방식은 싱글 스레드의 Event Loop가 계속해서 돌아가면서 Event Queue에 요청이 들어오면 Thread Pool에 분배하여 넣어 비동기적으로 처리하도록 한다.

    Node.js Event Loop

    Thread Pool은 생성 비용이 비싼 스레드를 필요할 때 편하게 늘리기 위해 스레드를 미리 만들어주고 필요한 작업에 할당하는 방식이다. Nginx는 오랜 시간이 소요되는 작업에 대해 Thread Pool에 처리를 위임하고 다른 이벤트를 처리하여 Non-Blocking을 제공한다.

     

     

    Context Switching 최적화

    Nginx는 Core개수만큼 worker process를 생성하고, worker process는 하나의 Core만을 이용하도록 할당한다. 따라서 CPU에서는 프로세스를 변경하는 Context Switching을 거치지 않아도 되기 때문에 CPU의 부하가 감소한다.

     

     

     

     

     

    Nginx를 사용하는 이유

    웹 서버로서 Nginx를 많이 사용하는 이유는 무었일까? 이전에 언급했던 Event-Driven, Thread Pool 등을 통한 비동기 이벤트 처리 방식 이외에도 Nginx는 다양한 이점을 제공한다.

     

     

    1. 높은 성능과 적은 메모리 사용

    • 비동기 I/O처리 방식을 사용하여 높은 성능을 제공 → 대규모 웹사이트에서도 빠른 응답시간 보장
    • 적은 메모리 사용량으로 높은 성능 제공 → 서버 운용 비용 절감

     

     

    2. 리버스 프록시를 통한 로드 밸런서

    프록시는 인터넷 접속을 할 때 보안상의 문제로 직접 통신을 주고 받을 수 없을 때 그 사이의 중계기로써 대리로 통신을 수행하는 기능을 한다. 이런 중계 기능을 하는 것을 프록시 서버라고 한다. 프록시는 포워드 프록시와 리버스 프록시로 구분된다.

     

    ▷ 포워드 프록시

    클라이언트와 인터넷 사이의 영역으로 클라이언트가 정보를 요청하면 포워드 프록시가 받아 서버에게 전달한다. 응답도 마찬가지로 동작한다. 이는 몇가지 이점을 준다. 

    • 클라이언트 IP주소가 웹 서버에 노출되지 않음 → 클라이언트 식별이 어려워져 보안 강화
    • 특정 IP주소, 도메인, URL에 대한 접근 제한 가능
    • 미디어 스트리밍 지원 → 큰 용량의 미디어 파일을 클라이언트에게 빠르게 제공

     

    ▷ 리버스 프록시

    인터넷과 백엔드 사이의 영역에서 존재한다. 이는 몇가지 이점을 준다. 

    • 로드 밸런싱을 제공하여 WAS서버가 여러 대 일때 웹서버가 여러 요청을 각 WAS서버로 분배
    • 캐싱 서버로 이용 가능 → 사이트 접속 속도 빠름
    • WAS의 민감한 데이터를 숨겨 보안 높임

     

     

    3. SSL 지원

    SSL(Secure Sockets Layer)은 웹 사이트와 사용자 간의 통신을 암호화하고 보안을 유지하는데 사용되는 프로토콜이다. SSL은 HTTPS(HTTP Secure)로 알려진 보안 HTTP 프로토콜 기반 기술이다. SSL 프로토콜을 사용해 웹 서버와 클라이언트 간의 보안 연결을 설정하고 SSL 인증서를 사용하여 서버의 신원을 인증할 수 있다. 또한 보안 위협을 방지하고 기밀 정보를 보호한다.

     

     

    4. 데이터 압축

    클라이언트가 보내는 요청이 text일 경우 gzip을 사용하여 데이터 압축이 가능하다.

     

     

    5. 비동기 처리

    이벤트 루프 방식을 사용하여 높은 성능을 제공한다. 동시에 여러 요청이 들어왔을 때도 많은 트래픽을 동시에 처리할 수 있어 빠른 응답시간을 보장한다.

     

     

    6. 동적인 설정 변경

    Event-Driven의 특징 덕분에 서버 실행 시에도 동적으로 설정을 변경할 수 있다.(service reload)

    service reload를 하면 master process는 새로운 설정파일을 읽어 새롭게 워커 노드를 생성하고 기존 워커 프로세스에는 이벤트를 할당하지 않는다. 기존 워커 프로세스가 모든 커넥션을 처리하고 나면 새로운 워커 프로세스로만 이벤트를 전달하고 기존의 워커 프로세스를 종료한다.

     

     

     

    다양한 기능을 제공하는 Nginx는 좋은 점만 있을까?

    프로세스를 종료하게 되면 해당 프로세스가 관리하고 있던 모든 커넥션이 끊기게 된다. 이 문제로 개발자가 직접 모듈을 만들기가 까다롭다. 동적 컨텐츠를 처리할 수 없기 때문에 동적 콘텐츠에 대한 요청을 처리하려면 외부로 전달하고 다시 콘텐츠를 전송받을 때까지 기다려야한다.

     

     

     

     

    Nginx와 Apache의 차이

      Apache Nginx
    요청 처리 방식 클라이언트 접속마다 Process 혹은 Thread 생성 Event-Driven 방식으로 고정된 프로세스만 생성하고 내부에서 비동기적으로 처리
    C10K문제 CPU와 메모리 사용 증가 및 프로세스 생성 비용으로 한계 추가적인 생성 비용이 없고 비동기 이벤트 기반으로 적은 양의 스레드 사용
    Blocking 요청을 처리하지 못하고 완료될 때까지 대기 Thread Pool을 통해 대기 없이 비동기 처리
    장점 OS 안정성(window, unix 동일한 성능)
    동적 모듈 지원
    다중 커넥션 처리 가능
    로드밸런서
    단점 다중 커넥션 처리 어려움
    자원(CPU, 메모리 등)활용 비효율적
    동적 모듈 어려움(동적 컨텐츠 불가)

     

     

     

     

     

     


    참조

    댓글

Designed by Tistory.