본문 바로가기

기타

[NGINX] NGINX 란?

반응형

1. nginx ?

nginx 는 경량 웹서버로 정적파일을 serving 하는 web server 또는 요청을 다른 서버로 전달하는 reverse proxy server 로 활용되어 was 의 부하를 줄이는 로드 밸런서로 사용할수도 있다.

 

nginx 와 많이 비교되는 것이 apache 의 웹서버이다. 이둘의 차이는 요청을 처리하는 방식이다. apache 웹서버의 경우 요청마다 새로운 쓰레드를 생성하여 요청을 처리한다. 그렇기 때문에 요청이 많으면 많을수록 자원이 많이 소모된다. 반면에 nginx event-driven 구조로 동작하는데, 이때문에 하나 또는 고정된 개수의 프로세스만 생성되고, 요청들은 concurrency 하게 처리된다. 그렇기 때문에 보다 적은 자원으로도 효율적인 운용이 가능하다.

2. nginx 구조

nginx 는 설정파일을 읽고 유효성을 검사하는 master process 와 요청을 처리하는 worker process 로 구성된다. nginx event-driven 모델을 사용하고 worker process 사이에 요청을 효율적으로 분배하기 위해 OS 에 의존적인 메커니즘을 사용한다. worker process 의 개수는 설정 파일에서 정의되고, 정의된 프로세스 개수와 사용가능한 CPU 코어 숫자에 맞게 자동으로 조정된다.

3. nginx 설정

nginx 는 nginx.conf 라는 설정파일에 설정된 값을 통해 작동한다. nginx.conf 는 기본적으로 /etc/nginx/nginx.conf 에 위치하고 해당 위치에 없으면 /user/local/nginx/conf/nginx.conf 또는 /usr/local/etc/nginx/nginx/conf 의 경로를 찾아서 설정한다.

 

nginx 모듈은 설정파일에 있는 지시어, directive 에 의해 제어된다. directive 는 simple directive 와 block directive 두가지 종류가 있다.

- simple directive

이름과 값이 있고 세미콜론으로 끝난다.

 

worker_process 1;

- block directive

블럭을 통해서 여러 directive 를 감싼 형태로 정의된다.

 

http {
    server {
        location / {
	        root /path/to/html;
        }

        location /images/ {
    	    root /path/to/image;
        }
    }
}

- directive 키워드와 예제

http

http 블록은 HTTP 통신과 관련된 모듈의 지시어 블럭을 정의하는 블럭이다.

 

http, server, location 블럭은 계층구조를 가지고 있어서 http 블럭안에 server 와 location 블럭이 위치할 수 있다. 계층구조에 따라서 상위 블럭에서 정의한 지시어는 하위 블럭에 값이 상속된다. 예를들어 http 블럭에서 정의한 값은 server 블럭의 기본값이 되고 server 블럭에서 정의한 값을 location 블럭의 기본값이 된다. 만약 하위 블럭에서 해당 설정을 새로 정의하면 상위 지시어는 무시되고 새로 정의된 값으로 설정된다. http 블럭 안에 한 개 이상의 server 블럭을 선언할 수 있다.

server

하나의 호스트를 선언하는데 사용하는 블럭으로 http 블럭 안에서만 사용할 수 있다. server 블럭에는 한 개 이상의 location 블럭을 선언할 수 있다.

location

location 블럭은 server 블럭 안에 정의되고, 특정 url 을 처리하는 방법을 정의한다.

events

events 블럭은 네트워크의 작동 환경을 설정하는 블럭이다. events 블럭의 지시어는 events 블럭 내부에서만 사용할 수 있고, http, server, local 블럭과는 상속 관계를 가지지 않는다.

 

events 블럭에서만 사용되는 지시어들은 다음과 같다.

 

# LISTEN 소켓을 오픈하기 위한 accept mutex 의 사용/해제를 설정한다.
accept_mutex on;

# 자원 획득을 다시 시도하기 전에 worker process 가 기다려야 하는 시간을 정의한다.
# accept_mutex 가 off 되어있으면 해당 지시어는 사용되지 않는다.
accept_mutex_delay 500ms;

# worker process 가 동시에 처리할 수 있는 접속자 수를 정의한다.
# worker_processes * worker_connections 를 계산한 값이 nginx 서버의 최대 접속자 수이다.
worker_connections 1024;

4. reverse proxy

nginx 는 reverse proxy 로도 활용할 수 있다. reverse proxy 는 클라이언트와 서버 사이에서 중개자 역할을 하여 요청들을 설정에 따라 알맞은 내부 서버로 접근할 수 있도록 도와주는 서버이다. 이를 통해서 내부 서버의 외부 노출을 방지하고 SSL 사용등을 통한 보안과 요청을 분산시키는 로드밸런싱의 역할을 할 수 있다.

 

reverse proxy 설정의 예시는 다음과 같다. 아래의 예시는 80 포트로 들어오는 요청을 127.0.0.1:8001 서버로 전달하도록 설정되어 있다. 만약에 listen 으로 포트 설정이 되어있지 않으면 기본값인 80 으로 설정된다.

 

http {
    server {
        listen 80;
        location / {
	        proxy_pass http://127.0.0.1:8001;
        }
    }
}

※ reverse proxy

리버스 프록시는 인터넷과 서버 사이에 존재하는 프록시 서버로 실제 서버를 대신하여 클라이언트의 요청을 받아서 동작한다. 리버스 프록시를 이해하기 위해서는 먼저 포워드 프록시를 이해하고 이와 비교하는 것이 편리하다.

 

포워드 프록시는 우리가 일반적으로 떠올리는 프록시의 유형으로 클라이언트와 인터넷 사이에 위치하여 클라이언트 정보가 서버에 노출되지 않도록 한다. 그외에도 서버로부터 받은 html, css, js 등과 같은 정적파일을 캐싱하여 응답 성능을 높이고 서버의 부하를 줄이는 기능도 한다. 그외에도 내부망의 프록시를 통해서 특정 주소에 대한 액세스 차단 등을 할수도 있다.

 

반면에 리버스 프록시는 클라이언트가 아닌 서버측에 위치하게 되는데, 포워드 프록시가 다양한 클라이언트들의 요청을 받아서 대신 서버에 요청하는 것과 다르게 리버스 프록시는 요청을 대신 받아서 다양한 서버들에게 요청을 전달한다. 이를 통해 프록시 서버에 암호화를 설정이나 여타 서버 공격들이 실제 서버가 아닌 프록시 서버를 공격하도록 함으로써 서버들을 보호할 수 있다. 그리고 프록시 서버로 오는 요청들을 분산하여 한 서버에만 부하가 되지 않도록 로드밸런싱의 기능도 수행한다.

5. nginx 실행 예제

docker-compose 를 사용하여 nginx 웹서버 설정과 컨테이너 실행을 통해서 웹서버에 접속해보는 예제를 진행한다.

- docker-compose.yml

version: '3'
services:
  nginx:
    image: nginx:latest
    ports:
      - 80:80
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./static:/static
    container_name: web-proxy

 

docker-compose.yml 을 확인하면 volume 을 통해 외부의 nginx.conf 를 컨테이너 내부와 공유한다. /etc/nginx/nginx.conf 에 외부에서 설정한 nginx.conf 를 공유하여 해당 설정으로 웹서버가 실행되도록 한다.

- nginx.conf

# user: worker process 를 실행할 사용자를 설정. 사용자에 따라서 권한 등이 달라질 수 있다.
user  nginx;

# worker_processes: worker process 의 개수 정의
worker_processes  auto;

# error_log: nginx logging 설정. log file 과 logging level 을 설정한다.
error_log  /var/log/nginx/error.log warn;

# pid: main process 의 pid 를 저장할 파일을 지정한다.
pid /var/run/nginx.pid;

# events 는 nginx 서버와의 접속과 관련된 설정들을 정의하는 지시어 블럭이다.
events {
    # worker process 에 최대 동시 접속 수를 지정한다.
    worker_connections  1024;
}

# HTT 접속에 대한 설정을 하는 지시어 블럭이다.

http {

    # 외부의 파일을 읽어와서 파일에 설정된 지시어와 블럭들을 설정에 적용한다.
    Include /etc/nginx/mime.types;

    # response 의 MIME 타입을 정의한다.
    default_type application/octet-stream;

    # log_format: log 형식을 설정한다.
    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: logging 파일을 설정한다. Logging 형식은 log_format 에서 정의한 main 형식으로 저장한다.
    access_log  /var/log/nginx/access.log  main;

    # upstream 을 서버로 들어온 request 들을 전달할 server 들의 그룹을 설정한다.
    # upstream group 의 이름은 후에 proxy_pass 에서 참조하여 사용할 수 있다.
    # 해당 upstream 으로 pass 된 request 들은 group 에 정의된 server 들 중 하나로 전달되어 처리된다.
    # 만약 아무런 알고리즘 설정이 되어있지 않으면 Round-Robin 방식으로 타겟 서버가 결정된다.
    upstream web-web {
        server web:3000;
    }

    # upstream 에 load balancing 알고리즘을 설정하여 request 들을 분배할 수 있다.
    upstream web-api {
        Ip_hash; # ip address 를 hash 값으로 사용하여 request 를 분배한다.

        # weight: 서버의 가중치로 가중치가 1 (기본값) 인 서버보다 3배 많은 request 를 할당한다.
        server web:8080 weight=3;

        # max_conns: worker 별로 동시에 연결할 수 있는 최대 request 를 설정한다.
        server web:8081 max_conns=256;

        # max_fails: request 의 최대 실패를 설정한다. max_fails 를 초과하면 다른 서버에게 request 가 전달된다.
        # fail_timeout: timeout 시간을 설정한다. timeout 시간을 넘어가면 request fail 로 간주한다.
        server web:8082 max_fails=3 fail_timeout=30;
   
        # backup: backup 서버로 지정하여 주요 서버들에 장애가 생기면 그때부터 해당 서버로 request 가 pass 된다.
        server web:8083 backup;
    }

    # server: 어떤 서버가 http request 를 처리할지 설정한다.
    server {
        # listen: port 를 설정한다.
        listen 80;

        # root: request 의 root address 를 설정한다.
        root /static/;

        # location: request 의 URI 별로 requset 를 처리하는 설정을 한다.
        location /static {
          root /static/;
        }

        location /api {
            # proxy_pass: 해당 location request 를 proxy_pass server 와 매핑하여 해당 서버로 request 를 전달한다.
            # 여기서 web-api 는 upstream 으로 지정되어 있기 때문에 해당 server group 에서 request 를 처리한다.
            proxy_pass         http://web-api/
        }

        location / {
            proxy_pass         http://web-web/;
        }
    }
}

 

보다 다양하고 자세한 directives 들은 다음의 링크에서 확인할 있다.

 

 

Alphabetical index of directives

 

nginx.org

 

 

 

[Reference]

 

Alphabetical index of directives

 

nginx.org

 

[Nginx] Nginx 이해하기

Nginx? Nginx는 간단하게 말씀드리자면 경량 웹 서버입니다. 클라이언트로부터 요청을 받았을 때 요청에 맞는 정적 파일을 응답해주는 HTTP Web Server로 활용되기도 하고, Reverse Proxy Server로 활용하여 W

icarus8050.tistory.com

 

[Nginx] 리버스 프록시로 사용하기 (백업 서버 설정, 로드 밸런싱)

Upstream Nginx를 리버스 프록시로 이용하기 위해서는 nginx의 내장 모듈 중의 하나인 upstream 모듈을 사용하면 된다. upstream 모듈은 proxy_pass등의 지시자에 의해 참조되며 nginx가 받은 요청들을 처리할

jizard.tistory.com

 

포워드 프록시와 리버스 프록시

프록시 (Proxy) 프록시란? 프록시는 클라이언트와 서버 사이에 위치한 중계 서버로 통신을 대신 수행하는 대리자 역할을 한다. 프록시가 없다면 클라이언트는 서버와 직접 통신한다. 반면, 클라이

hudi.blog

 

 

반응형

'기타' 카테고리의 다른 글

[Celery] Celery 란?  (0) 2023.06.01
[FastAPI] BackgroundTasks  (0) 2023.05.26
[MongoDB] Aggregation  (0) 2023.05.02
[Gradle] Gradle 사용법 - 설치, 초기화 및  (1) 2023.01.17
[Gradle] Gradle 이란?  (1) 2023.01.14