Frontend

[Nginx] Nginx란?

취업하고싶다! 2025. 4. 7. 14:26
반응형

 

대부분의 백엔드 개발자가 갖춰야 할 기본 스킬 중 하나가 Nginx다. 하지만 프론트엔드 개발자도 백엔드 개발자와의 원활한 협업을 위해서는 Nginx에 대한 기본 개념을 어느정도 알고있어야 한다고 생각이 들어서 Nginx에 대해 공부해보고자 한다.

 

[ Nginx 공부 전 알아야 할 CS ]

클라이언트

  • 서비스를 이용하기 위해 네트워크를 통해 요청을 보내는 주체
  • 웹 개발 영역에서 보통 클라이언트라 하면 크롬, 사파리, 익스플로러 등 웹 브라우저를 의미

 

웹 서버

  • 클라이언트의 요청에 따라 HTML, CSS, JS, 이미지 파일과 같은 정적 파일을 응답하여 제공하는 소프트웨어
  • HTTP 프로토콜을 사용해 클라이언트와 통신
  • 대표 : Nginx, Apache 등

 

WAS

  • 클라이언트 요청에 대해 동적인 처리를 담당하는 영역
  • 웹 서버와 달리 애플리케이션 로직을 실행할 수 있도록 구성
  • 대표 : Tomcat, JBoss 등

 

 

웹 서비스 동작 방식

  • 요청 : 클라이언트 > 웹서버 > WAS > DB
  • 응답 : DB > WAS > 웹서버 > 클라이언트

 

웹 서버 사용하는 이유

  • WAS 부담 덜어줌(정적 정보(서버에 응답이 필요없는, 단순하게 서버가 사용자에게 전달하면 끝나는 데이터)를 웹 서버가 처리해줌)
  • 보안 기능 제공(SSL/TLS)
  • 높은 성능 제공
    • 비동기 처리 방식 사용 -> 높은 성능
    • 이벤트 기반, 멀티 프로세싱, 스레드 풀 사용 -> 수천 대의 클라이언트 요청 동시에 처리

 

 

[ Nginx를 사용하는 이유 ]

정적 파일 제공해 주는 웹 서버로 활용, 프록시 서버로드밸런서로 활용

Reverse Proxy를 통한 로드 밸런싱

  • Port Proxy
    • ex) 80 > 8000
  • Path Proxy
    • 80/irish -> 8000
    • 80/irish1 -> 8001
    • 80/irish2 -> 8002
  • 높은 성능과 적은 메모리 사용

 

 

[ Nginx vs Apache Web Server ]

Web Server에서 1,2위를 다투는 것이 Nginx와 Apache Web Server이다.

참고로 Apache Web Server가 Nginx보다 먼저 세상에 나왔다. 이 둘의 차이점은?

 

Apache Web Server

  • 등장 : 인터넷 보급이 활발하지 않은 시대에 등장
  • 중점 : 안정성, 확장성
  • 단점
    • 아파치의 구조 : Process Driven(1요청 1프로세스)
    • 따라서 수많은 동시 커넥션을 처리하기에는 부적합(ex: C10K - 요청이 순간적으로 몰려 동시에 1만건 이상이 들어오면 1만건 이상의 프로세스 생성을 하지못해 처리가 불가능)
    • 이유 : 인터넷 보급이 활발하지 않은 시대에 등장했기 때문에 수많은 프로세스를 생성하는 것에 한계가 존재

 

Nginx

  • 등장 : 트래픽이 증가하면서 Apache의 한계를 극복하기 위해 Nginx가 등장
  • 중점 : 동작 원리 - Nginx는 Event-Driven(하나의 프로세스에 여러 이벤트 쌓아서 처리) 구조로 동작하기 때문에 한 개의 프로세스만 생성하여 사용하고 비동기 방식으로 요청들을 동시적으로 처리

 

Event-Driven(비동기처리방식)
요청이 들어오면 어떤 동작을 해야하는지만 알려주고 다른 요청을 처리하는 방식
따라서 CPU와 관계없이 모든 입출력들을 전부 Event Listener로 전달하기 때문에 흐름이 끊기지 않고 응답이 빠름

 

 

[ Nginx 구조 ]

 

Nginx는 하나의 master process와 worker process로 구성

master process는 설정 파일을 읽고 설정에 맞게 worker process를 구성

worker process가 생성될 때 각자 지정된 listen 소켓을 배정 받고 그 소켓에 클라이언트의 여러 요청들을 받고 처리할 수 있다

이런 connection 형성, 제거, 새로운 요청을 처리하는 것을 event 라고 한다

 

 

 

OS 커널이 이 event들을 queue 형식으로 worker process에게 전달

이 event는 queue에 담긴 상태에서 worker process가 처리해줄 때까지 비동기 방식으로 대기하다가 worker process가 하나의 스레드로 event로 꺼내 처리한다

-> worker process가 쉬지 않고 계속해서 일을 하기 때문에 자원을 효율적으로 사용 가능(apache는 요청없으면 프로세스 방치됨)

 

Event Driven 방식이 요청을 스택처럼 쌓아서 처리하는 형식이라 했는데, 이런 구조의 단점으로는 요청 하나가 길면 남은 요청은 기다릴 수 밖에 없다

그 단점을 1.7.11버전 이후 Thread Pool이라는 개념을 도입해 해결

-> 시간이 오래 걸리는 작업의 경우 Thread Pool에 event를 위임하고 큐 안의 다른 event를 처리

 

 

 

이러한 worker process는 보통 cpu 코어 개수만큼 생성하기 때문에 Context Switching 사용도 줄일 수 있다

하지만 개발자가 기능 추가를 시도했다가, 돌아가고 있는 worker process를 종료하게 되면 해당 worker process가 관리하고 있던 connection과 관련된 요청을 더 이상 처리할 수 없게되는 문제가 생김

-> 따라서 Nginx개발자가 직접 모듈을 만들기가 까다롭다는 단점 존재

 

 

 

[ Nginx 장점 ]

1. 동시 커넥션 양 최소 10배 증가(일반적으로 100 ~ 1000배 증가)

2. 동일한 커넥션 수일 때 속도 2배 향상

3. 동적 설정 변경 - ex) 운영 도중에도 서버 추가 가능

 

 

[ Nginx의 핵심 기능 ]

1. 리버스 프록시(Reverse Proxy)

리버스 프록시클라이언트 요청을 대신 받아 내부 서버로 전달해주는 것을 말하는데 이를 통해 서버 정보를 클라이언트로부터 숨겨줌

 

위처럼 구성하여 `/` 로 요청 시 3000번 포트로 매핑

`/api` 로 요청 시 8080번 포트로 매핑

 

 

2. 로드밸런싱(Load Balancing)

로드밸런싱하나의 서버에서 받는 요청을 여러 대의 서버가 분산 처리할 수 있도록 요청을 나누어 주어 성능, 확정성, 신뢰성 향상 가능

 

 

3. 캐싱(Caching)

클라이언트가 요청한 내용을 캐싱하여 같은 요청이 오면 캐시에 저장된 내용을 전송전송 시간 절약, 불필요한 외부 전송 방지

 

 

 

[ 무중단 배포 ]

기존 프로젝트를 업데이트하기 위해서는 서버를 재부팅 하기위해 잠시 서버를 끄는 시간이 필요하다

하지만 무중단 배포를 지원하면, 서버가 끊김없이 업데이트 사항을 바로 적용 가능

 

NGINX의 리버스 프록시(reverse proxy)의 특징을 통해 다음과 같은 행동 가능

port:8081이 구버전 서버라면 port:8082는 업데이트가 적용된 ver 1.1

Nginx의 config 파일을 들어가서 요청을 건네주는 port만 1.0서버에서 1.1서버로 변경 후 nginx reload 명령을 프롬포트에서 입력하면 끊김없는 무중단 배포 구현 가능

 

 

[ 코드 구현 ]

nginx.conf

user nginx;
worker_processes  auto;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

	# 백엔드 upstream 설정
    # upstream myweb-api {
    #     server api:8080;
    # }

	# 프론트엔드 upstream 설정
    upstream next-server {
        server 172.17.0.1:3000; # docker를 사용하지 않는다면 localhost:3000(웹서버주소)
    }

    server {
        listen 80;

		# /api 경로로 오는 요청을 백엔드 upstream 의 /api 경로로 포워딩
        # location /api {
        #     proxy_pass         http://myweb-api/api;
        # }

		# / 경로로 오는 요청을 프론트엔드 upstream 의 / 경로로 포워딩
        location / {
            proxy_pass         http://next-server/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    }
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    keepalive_timeout  65;
    # include /etc/nginx/conf.d/*.conf;
}

 

주의깊게 봐야할 부분은 http 블럭 안의 upstream 블럭server 블럭이다.

1. 사용자가 nginx 서버 주소로 요청(localhost:80). 기본적으로 http는 80포트를 사용하기 때문에 nginx에서는 listen 80포트로 구성

2. nginx 서버는 location 블럭에서 proxy_pass로 지정된 주소로 요청을 전달

3. 운영중인 서버가 localhost:8080 or localhost:3000이면 upstream 블럭에 localhost:8080, localhost:3000으로 작성(위 코드에서는 docker-compose 파일이 있다고 가정 -> 172.17.0.1로 작성)

4. nginx 서버 주소로 요청하면(localhost:80) proxy_pass로 지정한 웹 서버로 요청이 전달

 

 

docker-compose.yml

version: "3.8"

networks:
  corp:
    driver: bridge

services:
  nginx_proxy:
    image: nginx:1.21.5-alpine
    container_name: nginx_proxy    
    ports:
      - 80:80
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf

  next-client:
    container_name: next-client
    build:
      context: ./
      dockerfile: ./Dockerfile
    ports:
      - 3000:3000

 

 

docker-compose.yml 폴더 위치에 nginx 폴더를 생성하고 nginx.conf 파일을 생성

nginx_proxy 블럭 내용은 고정

next_client는 docker로 띄울 웹 서버의 정보

반응형

'Frontend' 카테고리의 다른 글

타입스크립트 - Mapped Types  (0) 2025.04.03
타입스크립트 - Conditional Types  (1) 2025.04.02
타입스크립트 - Utility Types  (0) 2025.04.02
도커(Docker)  (8) 2025.03.27
Submodule 구축  (0) 2025.03.11