Nginx 에 대해 알아보자

김연규·2022년 8월 1일
post-thumbnail

Nginx란 무엇일까?

nginx는 Apache처럼 정적 콘텐츠를 호스팅해주는 웹서버다.
하지만 대용량 Request 처리에 있어, Apache보다 성능상 장점을 가지고, 단순히 정적 콘텐츠 호스팅 뿐만아니라, 다양한 기능을 가지고 있다. 왜그럴까?


Apache와 Nginx의 비교

nginx 홈페이지에 가면 아래와 같이 적혀있다.

many web servers and application servers use a simple threaded or process‑based architecture, NGINX stands out with a sophisticated event‑driven architecture that enables it to scale to hundreds of thousands of concurrent connections on modern hardware.

위의 내용을 요약하자면 Apache는 프로세스 또는 쓰레드 기반인데 반해, nginx는 Event 기반 방식이기 때문에 동시에 처리할 수 있는 연결 수를 비약적으로 증가시킬 수 있다는 것이다.
그렇다면 프로세스기반과 Event기반의 차이점은 무엇일까?

1. Apache 등 기존 웹서버

  • nginx Document에서 예로 든 것이 체스다.
  • 1:1 체스라고 생각하면 된다. 즉, 하나의 Request를 하나의 Process가 담당한다.
  • 동작 순서는 아래와 같다.
    - Web Server Process가 새로운 Connection을 Listen Socket을 통해 기다림
    - 새로운 Connection을 맺게 되면 Client의 Response가 올 때까지 해당 프로세스 또는 쓰레드는 Blocking 상태가 됨
    - Client가 또다시 Request가 올때까지 기다리다가 (KeepAlive) Connection을 Close
    - 프로세스는 Listen 상태로 돌아감

2. Nginx

  • 체스로 예를 들면 체스 전문가가 여러명을 상대로 체스를 두는 것과 같다.
  • 동작 순서는 아래와 같다.
    - Worker 프로세스는 Listen Socket과 Connection Socket에서 이벤트를 기다림
    - Socket에서 이벤트가 일어나면?
    1. Listen Socket에서의 Event의 의미는 새로운 Reqeust 이므로, Worker는 Connection Socket을 만듬
    2. Connection Socket의 의미는 기존 연결된 Client Request이므로, Worker는 신속히 응답
    - Worker는 Blocking 상태에 빠지지 않는다. 특정 Client에게 Response를 했다면 바로 다음 Client로 간다. -> 응답주고 바로 다음 일으로 하러감. Non-blocking.

Nginx Process

nginx는 아래와 같이 4개의 프로세스로 구성되어 있다. 실질적인 Request 요청처리는 Worker Process가 한다.

1. Master Process

  • 설정 파일을 읽거나, 포트를 바인딩
  • 자식 프로세스 생성 (밑의 3개 프로세스)

2. Worker Process

  • Master Process의 자식으로 실질적인 요청을 처리
  • 보통 물리 코어 1개당 1개의 Worker Process를 권장
  • 네트워크 연결을 처리
  • 디스크에 컨텐츠 Read / Write
  • Upstream Server와 통신
  • 각 Worker Process는 Context Switching을 줄이기 위해 Non-blocking 방식으로 동작

3. Cache Manager Process

  • 주기적으로 실행된
  • 디스크 캐시를 설정된 사이즈로 유지하기 위해, 캐시 엔트리를 정리

4. Cache Loader Process

  • 디스크 기반 캐시를 메모리에 불러오고, 종료됨
  • nginx 시작 시 실행됨

Worker Process 내부 구조

  • Worker Process는 Master Process로 부터 Listen Socket을 제공 받는다.
  • 새로운 Connection 요청이 들어오면, 요청에 알맞은 State Machine에 할당된다.
  • State Machine은 Nginx에 요청을 처리하는 방법을 알려주는 명령 셋트다.

Nginx 의 주요 설정 파일과 디렉터리 및 명령어

1. 주요 설정 파일 및 디렉터리

  1. /etc/nginx
    • nginx 서버가 사용하는 기본 설정이 저장된 루트 디렉토리
    • nginx 는 이곳에 저장된 설정 파일의 내용에 따라 동작함
  2. /etc/nginx/nginx.conf
    • nginx 의 기본 설정 파일로, 모든 설정에 대한 진입점
    • 워커 프로세스 개수, 튜닝 동적 모듈 적재와 같은 글로벌 설정 항목을 포함하며, 다른 nginx 세부 설정 파일에 대한 참조를 지정
  3. /etc/nginx/conf.d
    • 기본 HTTP 서버 설정 파일을 포함
    • nginx 디렉터리 내 파일 중 이름이 .conf 로 끝나는 파일은 2번의 nginx.conf 파일 내 포함된다.
    • 즉, nginx 설정은 include 구문을 활용해 구조화함으로써 간결하다.
  4. /var/log/nginx
    • nginx 로그가 저장되는 디렉터리
    • access.log 와 error.log 가 있다.

2. 주요 명령어

  1. nginx -h : help
  2. nginx -v : 버전
  3. nginx -V : 버전과 빌드 정보 및 바이너리에 포함된 설정 인수값
  4. nginx -T : nginx 설정을 시험하고 설정 파일들을 화면에 보여줌
  5. nginx -s signal
    • stop : 즉시 동작 멈춤
    • quit : 현재 진행 중인 요청을 모두 처리한뒤 프로세스 종료
    • reload : nginx 가 설정을 다시 읽음
    • reopen : 지정된 로그 파일을 다시 염

실습

nginx 에는 여러가지 기능이 있다. 이번 블로그에서는 정적 컨텐츠 호스팅과 Reverse Proxy만 살펴 볼것이다.

nginx 기능

  1. 웹서버 - 정적 컨텐츠 호스팅
  2. Reverse Proxy
  3. Load Balancer
  4. API Gateway
  5. Contents Cache

웹서버 - 정적 컨텐츠 호스팅

상위 config 파일인 /etc/nginx/nginx.conf 파일에서 수정이 가능하고, 아니면 다른 config 파일을 import 하여도 된다.

  • 하기 config 파일을 참조하여 설정을 하면 된다.
    • 우선 대분류에 http가 있고, 그 밑에 server가 있다.
    • server 는 포트로 구분을 짓는다.
    • server 밑에는 location 이 있다.
    • location은 url Path 및 정적 컨텐츠가 있는 OS 내 Path가 들어간다.
    • 하기에는 80 포트와 8080 포트를 bind하였고, 각각 포트 별로 다른 Contents 파일을 호스팅할 수 있게끔 하였다.
http {

## Server #1 
    server {
        listen       80;
        listen       [::]:80;
       server_name  _;
        root         /data/www;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
   }

## Server #2
    server {
        listen       8080;
        server_name  _;

				location / {
			        	root         /usr/share/nginx/html;
				}

				location /www {
					root	/data;
				}

    }
}

Reverse Proxy

Request를 받아서 다른 서버로 해당 Request를 넘겨주기 위한 것이다.
보통 실무에서는 이 용도로 많이들 사용하는 것 같다.

  • 실습 환경
    • nginx 포트는 9090으로 설정한다.
    • 9090 포트로 Request를 받으면 127.0.0.1 의 80포트로 Reverse Proxy 한다.
    • 80포트는 httpd 의 포트로 정상적이라면 Apache 기본 페이지가 나올 것이다.
  • nginx config file
server {
        listen       9090;

				location / {
					proxy_set_header Host $host;  ## Header를 변경한다. 
					proxy_set_header X-Real-IP $remote_addr;  ## Header를 변경한다. 
					proxy_pass http://127.0.0.1;
			
				}
}
  • 추가적으로 Proxy Target이 Domain은 같으나, IP가 다른 경우라면 proxy_bind로 IP를 각각 둘 수 있다.
location /app1/ {
    proxy_bind 127.0.0.1;
    proxy_pass http://example.com/app1/;
}

location /app2/ {
    proxy_bind 127.0.0.2;
    proxy_pass http://example.com/app2/;
}
profile
개발자

0개의 댓글