Nginx

2024. 7. 1. 17:47BE & Infra


Apache는 클라이언트 마다 커넥션을 제공해주어야 한다.

하지만, 클라이언트가 10k가 넘어간다면 메모리 부족과 같은 문제가 발생한다. 이 외에도 apache는 무겁다는 점에서 Apache는 수많은 동시 서버를 감당하기에는 적합하지 않다. 물론 Apache는 지금까지도 계속해서 발전하고 있다.

 

Apache가 가지는 구조적 한계를 nginx를 이용해 해결하고자 했다. 

 

apache 서버 이전에 nginx를 설정해, 수많은 connections들을 nginx가 따로 관리하도록 한다. nginx는 웹서버이다. 즉 정적 파일의 경우 뒤의 apache로 가지 않아도 된다.

 

nginx의 구조는 master process가 존재하며, 이를 통해 worker process를 만든다. 이 process 내에서 queue의 구조로 커넥션의 연결, 제거 등을 포함하는 이벤트들을 관리한다. 이는 아파치에서 커넥션당 하나의 프로세스를 할당하고, 요청이 없을 때에는 프로세스가 아무일도 하지 않는 것을 생각하면 훨씬 효율적이라고 할 수 있다. 만일 Disk IO가 필요하다면 이를 thread pool을 위임하고 queue안의 다른 일을 처리한다. core당 process를 만들어 contextswitch의 개수를 줄인다. 

 

설정에 변경이 생긴다면 새로운 worker process들을 만들고, 이전 worker process가 종료되면 사라진다. 이러한 동시 커넥션을 유지한 채 뒷단에 서버를 추가할 수 있다. 이벤트 구조이기에 가능하다.

 

apache 서버와 nginx는 대립관계라기 보다 목적성에 차이를 가지고 있댜. apache는 안정성에 초점을 맞춰 호환성과 여러 모듈들을 사용하는 확장성에 목적을 두고 있다. nginx 이와 달리 C10K와 같은 동시 커넥션 문제를 해결하는 것에 목적성을 가지고 있다.

 

 

Nginx의 주요 기능들

- 웹 서버

- 로드 밸런서

- 웹 서버 가속기 (client는 https를 이용해서 nginx로 nginx는 server로 http로)

- 캐싱, nginx를 클라이언트 쪽에 생성해 캐시 역할을 할 수 있다.

 

추가적인 기능들

- hsts

- cors 처리

- tcp/udp 커넥션 부하 분산

- http/2

 

 


## 필자가 적용했던 nginx 기본설정(https, 로드밸런서)

upstream backend {
    server localhost:8080;
}

upstream frontend {
    server localhost:3000;
}

# HTTP 서버 블록
server {
    listen 80;
    server_name {server 주소};

    # HTTP에서 HTTPS로 리디렉션
    return 301 https://$host$request_uri;

    # letsencrypt 인증서 갱신 요청 처리
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
}

# HTTPS 서버 블록
server {
    listen 443 ssl;
    server_name {server 주소};

    # SSL 설정
    ssl_certificate {파일경로};
    ssl_certificate_key {파일경로};
    ssl_trusted_certificate {파일경로};

    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 5m;
    ssl_stapling on;
    ssl_stapling_verify on;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
    ssl_prefer_server_ciphers off;

    add_header Strict-Transport-Security "max-age=63072000" always;

    # 프록시 헤더 설정
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # API 요청을 백엔드 서버로 프록시
    location /api/ {
        proxy_pass http://backend;
    }

    # 모든 다른 요청을 프론트엔드 서버로 프록시
    location / {
        proxy_pass http://frontend;
    }

    # letsencrypt 인증서 갱신 요청 처리
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
        try_files $uri $uri/ =404;
    }
    
}

 

 

 

 

 

 

 

'BE & Infra' 카테고리의 다른 글

RabbitMQ  (0) 2024.08.23
N+1 문제 정리  (0) 2024.08.18
JPA 기본편 정리  (0) 2024.07.19
WebRTC  (0) 2024.07.15