Nginx 적용하기 - woowacourse-teams/2020-songpa-people GitHub Wiki
Nginx 란?
비동기 이벤트 기반의 웹 서버 소프트웨어.
우리가 배포하는 Spring Boot Application은 was(내장 톰캣)을 포함하고 있지만 웹 서버는 포함하고 있지 않다.
웹 서버의 역할
클라이언트로부터 HTTP 요청을 받아들이고 정적 자원(html, 이미지 파일 등)을 제공하는 서버이다.
웹 서버는 정적 자원 요청을 받으면 즉시 응답하고 동적 자원을 요청받으면 was로 요청을 넘긴다.
웹 서버의 부속 모듈을 이용하면 네트워크간의 프록시 연결, SSL 설정 등을 할 수 있다.
was 앞 단에 웹 서버를 두는 이유는 자원을 효율적으로 관리하기 위해서이다. 정적 자원을 was 에서 내려줄 수도 있지만 was의 자원은 비즈니스 로직에 맞게 데이터를 가공하는 역할에 투자되야 한다. 웹 서버를 반드시 구축해야 하는 것은 아니지만 was가 동적 자원에 대한 요청을 효율적으로 처리하기 위해 웹 서버를 구축한다.
비동기 이벤트 기반 동작이란
- Apache 웹 서버의 동작 방식
클라이언트로부터 요청이 왔을 때 각 프로세스에서 스레드를 생성해서 요청을 처리한다.
요청이 늘어남에 따라 프로세스 생성 → 프로세스 내부에서 스레드 생성 과정이 반복되므로 메모리가 많이 필요하고 Context Switching 발생으로 부하가 걸릴 수 있다.
- Nginx 웹 서버의 동작 방식
비동기 이벤트 구동 방식으로 클라이언트의 요청을 병렬처리한다.
기본적으로 한 개 또는 고정된 프로세스의 수만 생성하고 프로세스 내부에서 비동기로 요청을 처리한다.
→ 동시 접속 요청이 많아도 프로세스 / 스레드 생성 비용이 발생하지 않는다.
비동기 처리로 인한 적은 메모리로 운용이 가능하다.
하지만 길고 많은 I/O 처리가 필요한 경우 시스템 큐에 요청이 쌓일 수 있어서 성능 저하가 발생할 수 있다.
Nginx Reverse Proxy
proxy 서버란 중계 서버이다.
→ 클라이언트 요청을 먼저 nginx에서 받은 후 우리가 배포하는 was에게 넘겨준다. was에서 처리한 결과를 nginx를 거친 후 다시 클라이언트에게 전달해준다.
→ 클라이언트는 모든 요청 / 응답을 was가 아닌 nginx와 수행한다.
Reverse Proxy
역방향 프록시. 우리가 nginx를 활용하는 방식이다. 외부에서 내부 서버로 접근 시 nginx를 거쳐서 들어오게 된다.
-
장점
보안: 외부 사용자는 실제 내부 서버의 존재를 몰라도 된다. 외부 클라이언트의 모든 요청은 reverse proxy 서버에게 들어오고 reverse proxy는 요청에 매핑되는 정보를 클라이언트에게 전달한다. 따라서 내부 서버의 정보를 외부로 숨길 수 있다.
로드 밸런싱: proxy 서버가 내부 서버의 정보를 알고 있으므로 로드 밸런싱을 통해 부하 여부에 따라 요청을 분배한다.
도입 배경(추가 필요)
- Https 적용
- 무중단 배포
EC2에 Nginx 적용하기
nginx 는 우리가 배포하는 jar파일이 있는 서버에 설치한다.
nginx를 ec2에 설치하기
$ sudo apt-get update
$ sudo apt-get install nginx
nginx가 성공적으로 설치되면 /etc/nginx
디렉토리가 생긴다.
- 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로 포워딩 해주고 있다.