Nginx 적용하기 - woowacourse-teams/2020-songpa-people GitHub Wiki

Nginx 란?

비동기 이벤트 기반의 웹 서버 소프트웨어.

우리가 배포하는 Spring Boot Application은 was(내장 톰캣)을 포함하고 있지만 웹 서버는 포함하고 있지 않다.

웹 서버의 역할

클라이언트로부터 HTTP 요청을 받아들이고 정적 자원(html, 이미지 파일 등)을 제공하는 서버이다.

웹 서버는 정적 자원 요청을 받으면 즉시 응답하고 동적 자원을 요청받으면 was로 요청을 넘긴다.

웹 서버의 부속 모듈을 이용하면 네트워크간의 프록시 연결, SSL 설정 등을 할 수 있다.

was 앞 단에 웹 서버를 두는 이유는 자원을 효율적으로 관리하기 위해서이다. 정적 자원을 was 에서 내려줄 수도 있지만 was의 자원은 비즈니스 로직에 맞게 데이터를 가공하는 역할에 투자되야 한다. 웹 서버를 반드시 구축해야 하는 것은 아니지만 was가 동적 자원에 대한 요청을 효율적으로 처리하기 위해 웹 서버를 구축한다.

비동기 이벤트 기반 동작이란

  • Apache 웹 서버의 동작 방식

image

클라이언트로부터 요청이 왔을 때 각 프로세스에서 스레드를 생성해서 요청을 처리한다.

요청이 늘어남에 따라 프로세스 생성 → 프로세스 내부에서 스레드 생성 과정이 반복되므로 메모리가 많이 필요하고 Context Switching 발생으로 부하가 걸릴 수 있다.

  • Nginx 웹 서버의 동작 방식

image

image

비동기 이벤트 구동 방식으로 클라이언트의 요청을 병렬처리한다.

기본적으로 한 개 또는 고정된 프로세스의 수만 생성하고 프로세스 내부에서 비동기로 요청을 처리한다.

→ 동시 접속 요청이 많아도 프로세스 / 스레드 생성 비용이 발생하지 않는다.

비동기 처리로 인한 적은 메모리로 운용이 가능하다.

하지만 길고 많은 I/O 처리가 필요한 경우 시스템 큐에 요청이 쌓일 수 있어서 성능 저하가 발생할 수 있다.

Nginx Reverse Proxy

proxy 서버란 중계 서버이다.

→ 클라이언트 요청을 먼저 nginx에서 받은 후 우리가 배포하는 was에게 넘겨준다. was에서 처리한 결과를 nginx를 거친 후 다시 클라이언트에게 전달해준다.

→ 클라이언트는 모든 요청 / 응답을 was가 아닌 nginx와 수행한다.

Reverse Proxy

역방향 프록시. 우리가 nginx를 활용하는 방식이다. 외부에서 내부 서버로 접근 시 nginx를 거쳐서 들어오게 된다.

  • 장점

    보안: 외부 사용자는 실제 내부 서버의 존재를 몰라도 된다. 외부 클라이언트의 모든 요청은 reverse proxy 서버에게 들어오고 reverse proxy는 요청에 매핑되는 정보를 클라이언트에게 전달한다. 따라서 내부 서버의 정보를 외부로 숨길 수 있다.

    로드 밸런싱: proxy 서버가 내부 서버의 정보를 알고 있으므로 로드 밸런싱을 통해 부하 여부에 따라 요청을 분배한다.

image

도입 배경(추가 필요)

  • Https 적용
  • 무중단 배포

EC2에 Nginx 적용하기

nginx 는 우리가 배포하는 jar파일이 있는 서버에 설치한다.

nginx를 ec2에 설치하기

$ sudo apt-get update
$ sudo apt-get install nginx

nginx가 성공적으로 설치되면 /etc/nginx 디렉토리가 생긴다.

image

  • conf.d: nginx 기본 설정 파일이 위치한 디렉토리
  • sites-available: nginx의 서버 설정 파일을 작성하는 디렉토리. 가상 서버 파일을 이 경로에 여러 개 만들 수 있다. 구동 시킬 가상 서버의 symlink를 /etc/nginx/sites-enabled에 만들면 된다.
  • sites-enabled: nginx의 서버 설정 파일의 symlink가 위치하는 디렉토리. 이 경로에 생성된 symlink파일을 읽어서 nginx 서버가 실행된다.

nginx가 제대로 설치되었는지 확인해보기 위해 nginx 서버를 실행시키고 브라우저를 이용해서 접속해본다.

nginx 서버 접속 경로는 ec2의 퍼블릭 ip로 접속하면 된다.

$ sudo service nginx start

/etc/nginx/sites-available/default 수정하기

server {
        listen 80;
        listen [::]:80;
        return 301 https://hashtagmap.tk$request_uri;

        location / {
                    proxy_pass http://127.0.0.1:8080;
        }
}

server {
        listen 443;
		
        access_log /var/log/nginx/reverse-access.log;
        error_log /var/log/nginx/reverse-error.log;

        location / {
                    proxy_pass http://127.0.0.1:8080;
        }
}
  • listen 80; : 80포트의 프록시 서버. http 연결을 받아들인다. https 연결을 받으려면 server 스코프를 listen 443 으로 하나 더 만들면 된다.
  • listen 443; : 443포트의 프록시 서버는 https 연결을 받아들인다.
  • return 301 https://hashtagmap.tk$request_uri; : 80포트는 http 요청만 받는다. http 요청을 지정한 https 요청으로 포워딩한다. 301 응답은 Moved Permanently 영구적인 URL 리다이렉션을 위해서 사용된다.
  • access_log, error_log: 프록시 서버로 들어오는 요청 기록, 에러가 발생했을 때 로그 파일의 저장 위치를 지정한다.
  • location / : http://{서버 IP}:80 으로 접속했을 때 포워딩해주는 위치를 지정한다. 경로별로 포워딩 위치를 지정할 수 있다. 127.0.0.1은 jar가 배포중인 ec2의 ip로 이어진다. localhost로 생각하면 된다.

위 파일을 작성했다면 nginx를 이용해서 가상 서버의 설정 파일을 작성한 것이다.

/etc/nginx/sites-enabled 에 symlink 생성하기

/etc/nginx/sites-available에 작성한 가상 서버 설정 파일 중 실행시키고 싶은 서버를 symlink로 만들어서 저장하는 경로다. 이 폴더에 위치한 가상서버 환경 파일들을 읽어서 서버가 세팅된다.

/etc/nginx/sites-available 폴더에 가상 서버 설정 파일의 이름을 default 로 작성했으므로 /etc/nginx/sites-enabled 폴더에서 다음 명령어를 입력한다.

$ sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled

해당 파일을 만들고 난 후 다음 명령어를 입력해서 nginx를 재시작 해준다.

$ sudo service nginx restart

현재 적용한 전체 Nginx 설정파일 내용입니다. (/etc/nginx/sites-available/default)

server {
    if ($host = themiso.kr) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

        listen 80;
        listen [::]:80;

        server_name themiso.kr;

        proxy_ssl_server_name on;

        return 301 https://themiso.kr$request_uri;

        include /etc/nginx/conf.d/service-url.inc;

        location / {
                 proxy_pass http://$service_url;
        }
}

server {
        listen 443;

        server_name themiso.kr;

        ssl on;
    ssl_certificate /etc/letsencrypt/live/themiso.kr/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/themiso.kr/privkey.pem; # managed by Certbot

        access_log /var/log/nginx/reverse-access.log;
        error_log /var/log/nginx/reverse-error.log;

        include /etc/nginx/conf.d/service-url.inc;

        location / {
                 proxy_pass http://$service_url;
        }

}

기존 설정과 변경된 점은 ssl 인증 정보에 대한 내용이 추가되어서 http -> https로 포워딩 해주고 있다.