Home Nginx란?
Post
Cancel

Nginx란?

웹 서비스의 순서

image

Web Server와 WAS

image

Web Server

웹 서버는 클라이언트로부터 HTTP 요청을 받아들이고, 해당 요청에 대한 정적인 콘텐츠(HTML 파일, 이미지, CSS, JavaScript 등)를 제공하는 소프트웨어이다.

WAS

WAS는 웹 어플리케이션을 실행하기 위한 환경을 제공하는 소프트웨어이다. 주로 동적인 웹 애플리케이션을 개발하고 배포하기 위한 서버 환경을 제공하며, 정적인 콘텐츠 또는 웹 서버에서 처리되는 정적인 요청과는 달리, 동적인 웹 페이지를 생성하고 실행하는 역할을 한다.

Web Server 종류

앞에서 웹 서버에 대해 말했는데, 웹서버에 가장 흔히 사용되는 것은 Nginx와 Apache가 있는데, 이것을 한번 알아보자.

image

아파치는 클라이언트의 요청이 들어올때마다 하나의 프로세스를 만든다. 프로세스를 만드는 작업에서 많은 시간이 소요되다보니 PREFORK방식으로 요청이 오기전에 미리 프로세스를 만드는 방식으로 구성되어있다. 하지만, 이러한 구조는 동시에 엄청나게 많은 커넥션이 있을때, 메모리 부족을 야기한다. 그래서 나온 개념이 Nginx이다.


Nginx는 이벤트 기반 처리 구조방식이다. 아까 말한 수많은 커넥션의 메모리 부하를 크게 줄이는 취지에서 나온 웹서버이다. PREFORK 방식은 커낵션마다 프로세스를 만드니까 요청이 많으면 메모리가 터질 수 있다. 그럼 도대체 이 많은 커낵션을 어떻게 유지할까?

비결은 Master Process에 있다. cd /etc/nginx/~/ ??.confg 하고 들어가면 있는 설정파일을 읽고 그에 맞는 Worker Process를 만든다. 그리고 그에 맞는 listen 소캣을 배정받는다. Worker Process는 보편적으로 CPU 프로세스 수만큼 master가 생성하고 관리한다.

  1. Master Process의 config 파일을 읽는다.
  2. Worker Process를 생성한다.
  3. Listen 소켓 배정한다.

Nginx

Nginx는 오픈 소스로 제공되는 웹 서버 및 리버스 프록시 서버 소프트웨어이다. 주로 웹 서버로 사용되지만, 로드 밸런싱, 리버스 프록시, HTTP 캐싱, SSL/TLS 지원 등 다양한 기능을 포함하고 있어 다양한 용도로 활용 될 수 있다.

Nginx를 사용하는 이유

1. Reverse Proxy 사용 가능

Forward Proxy

image

프록시(Proxy)의 사전적 정의는 “대리”다. 인터넷 접속을 할 때 보안상의 문제로 직접 통신을 주고받을 수 없을 때 그 사이의 중계기로서 대리로 통신을 수행하는 기능을 프록시라고 말한다. 이렇게 중계를 기능하는 것을 우리는 프록시 서버라고 부른다.


포워드 프록시는 클라이언트와 인터넷 그 사이에 있는 영역을 말한다. 클라이언트가 어떠한 정보를 요청하면 포원드 프록시가 이를 대신 받아서 서버에게 전달을 한다. 이후 서버의 응답 또한 포워드 프록시가 대신 받아 클라이언트에게 전달한다.


포워드 프록시를 사용하면 클라이언트의 IP 주소가 웹 서버에 노출되지 않는다. 따라서, 클라이언트의 위치나 신원을 식별하는 것이 어려워져 보안이 강화된다. 또한 접근 제어를 수행할 수 있다. 포워드 프록시를 사용하여 특정 IP 주소, 도메인 또는 URL에 대한 접근을 제한할 수 있다.


마지막으로 미디어 스트리밍을 지원할 수 있다. 미디어 파일은 일반적으로 큰 용량을 가지고 있기 때문에, 웹 서버에서 직접 전송하는 것은 효율적이지 않다. 포워드 프록시를 사용하여 미디어 파일을 캐시하고, 클라이언트에게 빠르게 제공할 수 있다.


Reverse Proxy

image

리버스 프록시는 인터넷과 백엔드 그 사이에 있는 서버 영역을 말한다. 예를 들어 WAS로 사용하고 있는 서버가 여러 대 있다고 가정을 해보자. 클라이언트가 https://test/blog1, https://test/blog2으로 접근을 했다면 blog1은 A 서버로 전달, blog2는 B 서버로 전달하여 요청에 해당하는 웹 서버로 길을 분배할 수 있다. 이것을 로드 밸런싱이라고 한다.


그리고 캐싱 서버로도 이용이 가능하다. 예를 들어 클라이언트가 이미지를 요청했을 때 처음에는 서버에서 가져오지만 이후에 동일한 요청이 있는 경우에는 캐시 서버에서 가져와 클라이언트게 전달해 준다. 이것으로 사이트의 접속 속도가 빨라지게 된다.


WAS가 데이터를 응답할 때는 기기의 명칭이나 주소 등 실제로는 민감이 정보들이 담겨져 있다. 이러한 정보들을 중간에서 숨겨줌으로써 보안을 높일 수가 있다.

로드 밸런싱

Nginx는 여러 서버 간의 트래픽을 균등하게 분배하여 부하를 분산하는 로드 밸런서로 활용된다. 이를 통해 서버의 성능을 최적화하고 가용성을 높일 수 있다.

SSL/TLS 지원

SSL (Secure Sockets Layer)은 웹 사이트와 사용자 간의 통신을 암호화하고 보안을 유지하는 데 사용되는 프로토콜이다. SSL은 HTTPS (HTTP Secure)로 알려진 보안 HTTP 프로토콜의 기반 기술이다.


HTTPS는 HTTP 프로토콜의 암호화된 버전이다. SSL 프로토콜을 사용하여 웹 서버와 클라이언트 간에 보안 연결을 설정하고, SSL 인증서를 사용하여 서버의 신원을 인증한다. 이를 통해 중간자 공격과 같은 보안 위협을 방지하고, 사용자의 개인 정보와 웹 사이트의 기밀 정보를 보호할 수 있다.

사용하는 방법

1. Nginx 연결

1. ec2 접속

1
ssh -i [pem 키] username@[ip 주소]

2. nginx 설치

1
$ sudo apt install nginx

3. nginx 시작

1
$ sudo systemctl start nginx

4. nginx 상태 확인(초록불 정상)

1
$ sudo systemctl status nginx

image

5. nginx 설정 파일 수정

1
$ sudo vi /etc/nginx/nginx.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# 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/;
        }
    }
}

6. nginx 재시작

1
2
$ sudo service nginx restart
$ sudo service nginx status

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
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 를 공유하여 해당 설정으로 웹서버가 실행되도록 한다.

즉시로딩과 지연로딩은 언제 사용하면 좋을까?

Spring bean container 생성부터 스프링 종료까지의 사이클