개발자는 기록이 답이다
Nginx로 Reverse Proxy 서버를 구축해서 로드밸런싱하기 본문
📌 웹 서버란?
웹 서버는 HTTP 요청을 받아들이고 해당 요청에 대한 응답을 제공하는 프로그램입니다.
주로 정적 컨텐츠를 제공하는 서버 (주로 정적 컨텐츠 캐싱이나 리버스 프록시 용도로 사용)로서 사용됩니다.
Apache와 Nginx는 가장 인기 있는 웹 서버 프로그램 중 두 가지입니다.
📌 Apache vs Nginx
Apache의 구동방식
- 오랜 기간동안 웹 서버로 사용되어 왔으며, 오픈소스 프로젝트로 가장 유명한 프로그램 중 하나입니다.
- Prefork MPM(Multi Processing Module) 방식
- HTTP 요청이 올때마다, 프로세스를 복제하여. 각각 별도 프로세스에서 해당 HTTP 요청을 처리합니다.
- 이러한 방식은 새로운 요청이 올때마다 새로운 프로세스를 생성해야 하므로 처리 속도가 느릴 수 있습니다.
- Worker MPM(Multi Processiing Module) 방식
- 하나의 HTTP연결 후에 복제된 프로세스 내에서 여러 스레드를 생성하여 여러 HTTP요청을 처리하는 방식입니다.
Nginx 구동방식
- Event Driven 방식으로 동작합니다.
- 하나의 프로세스로 동작하며, HTTP요청을 event로 보고 각 이벤트를 병렬로 처리할 수 있도록 비동기식으로 구현되었습니다.
- 대부분의 HTTP응답은 결국 html 파일을 제공하는 것이므로, IO작업이 발생합니다.
- 따라서 IO작업으로 event를 포워딩하고 요청 순이 아닌, 요청 작업이 끝난 순으로 처리한다.
- HTTP요청마다, 프로세스든 스레드든 생성이 필요없으므로, 시스템 자원 관리에 장점이 있습니다.
- 만약 1만명이 동시에 요청을 하면 Apache의 경우 1만개의 프로세스나 스레드가 실행되기 때문에, 메모리의 사용량이 증폭하기 때문에 자원 효율적입니다.
- 보통 많은 접속자가 있을 경우, 시스템 자원 관리 효율성때문에, Nginx가 보다 일반적으로는 성능이 좋을 수 있습니다..
- HTML 파일 사이즈, 어떤 추가 기능을 쓰느냐 등등 다양한 조건때문에 무조건 성능이 좋다라고 이야기 할 순 없습니다.
- 하나의 프로세스로 동작하며, HTTP요청을 event로 보고 각 이벤트를 병렬로 처리할 수 있도록 비동기식으로 구현되었습니다.
📌 Nginx reverse proxy
Proxy Server란?
클라이언트가 자신을 통해, 다른 네트워크 서비스에 접속하게 해줄 수 있는 서버를 의미한다.
Forward Proxy란?
클라이언트가 외부 인터넷에 직접 접근하는것이 아니라,
클라이언트가 Proxy Server에 외부 인터넷 접근 요청하고.
Proxy Server가 외부 인터넷에 대신 접속하여 결과를 받은 후, 클라이언트에 전달하는 서버
Reverse Proxy란?
클라이언트가 Reverse Proxy에 요청하면,
Reverse Proxy가 관련 요청에 따라, 적절한 내부 서버에 접속하여 결과를 받은 후 클라이언트에 전달
📌 Ubuntu Server에 Nginx 설치
# nginx를 설치하는 명령어
$ apt-get install nginx
# nginx 서비스를 시작하는 명령어
$ systemctl start nginx.service
# nginx 서비스의 현재 상태를 확인하는 명령어
$ systemctl status nginx.service
# nginx 서비스를 재시작하는 명령어
$ systemctl restart nginx.service
# nginx 서비스가 실행되지 않을 때 발생한 로그를 확인하는 명령어
$ journalctl -xe
Nginx를 설치하면 기본적으로 아래 2개의 파일을 확인하면 됩니다.
- /etc/nginx/nginx.conf
- /etc/nginx/sites-enabled/default
📌 nginx.conf
- ngix 웹서버 기본 설정 파일
- 크게 user, worker_processes, pid, events, http항목으로 이루어져있다.
- 이중 에서 http블록이 전체 웹 서버 기본 설정 항목
- http 블록 중 다음 항목으로 다양한 웹 서비스를 엽도 파일로 설정하는 것이 일반적이다
- /etc/nginx/conf.d/mysite.com.conf 형태로 웹 서비스별 설정을 별도 파일로 할 수 있다.
- 관련 파일에는 server 항목 설정(다음 default 파일의 server설정 에서 상세 내용 확인)
find -name nginx.cnf # 가볍게 위치만 확인
vi /etc/nginx/ngix.conf
Nginx의 웹서버가 하나니까 사이트 하나만 지원한다고 생각할 수 있지만,
웹 서버는 하나지만 여러 개의 사이트를 접근하는 경로별로 별도 서비스를 지원할 수 있게 설정할 수 있다.
그래서 /etc/nginx/conf.d/*.conf 처럼 파일을 만들어서 웹 서비스별 설정을 각각에 넣어줄 수도 있다.
- user www-data; : 웹서버를 돌리는 Id는 무엇인지?
- worker_processes auto; : 프로세스를 몇개 만들것인지? 여러개의 프로세스를 띄워서 이벤트를 받으면 좋습니다.
- pid /run/nginx.pid; : 시스템과 nginx의 프로세스와의 연결고리 관련 설정
- include /etc/nginx/modules-enabled/*.conf; : 다른 플러그인 설정 파일을 include
- events {} : 하나의 프로세스가 이벤트를 처리하는 방식에 대해 설정
- http {} :
user www-data; ## 웹서버를 돌리는 Id는 무엇인지?
worker_processes auto; ## 프로세스를 몇개 만들것인지? 여러개의 프로세스를 띄워서 이벤트를 받으면 좋다!
pid /run/nginx.pid; ## 시스템과 nginx의 프로세스와의 연결고리 관련 설정
include /etc/nginx/modules-enabled/*.conf; ## 다른 플러그인 설정 파일을 include
events { ## 하나의 프로세스가 이벤트를 처리하는 방식에 대해 설정
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
#mail {
# # See sample authentication script at:
# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
# # auth_http localhost/auth.php;
# # pop3_capabilities "TOP" "USER";
# # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
# server {
# listen localhost:110;
# protocol pop3;
# proxy on;
# }
#
# server {
# listen localhost:143;
# protocol imap;
# proxy on;
# }
#}
📌 default 파일의 server 설정
$ cd sites-enabled/
$ vi default
- listen은 HTTP요청을 받을 포트 설정
- default_server는 모든 웹 서버 요청을 받는다는 의미
- 두번째 줄의 listen(listen [::] 80)은 IPv6포트 관련설정이므로 무시해도 됨
server_name은 요청을 받을 도메인 이름 설정
localhost나 별도 도메인 이름이 없다면, 기본 설정(_)으로 놔두면 됨
----
📌 로드밸런싱이 되는지 확인하기 위한 API 작성
로드밸런싱이 제대로 이루어지는지 확인하기 위해 테스트용 API를 작성했습니다.
클라이언트로부터 요청이 들어왔을때 프록시 서버인 Nginx에서 내부 was서버로 로드밸런싱이 되는 것을 확인하기 위한 용도입니다.
default 파일을 삭제하고 spring-server라는 이름의 파일로 아래처럼 작성해줍니다.
root@nginx:/etc/nginx/sites-enabled# vi spring-server
upstream backend {
server {spring server 1 IP주소}:8080;
server {spring server 2 IP주소}:8081;
}
server {
listen 80;
server_name spring_server;
location / {
proxy_pass http://backend;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
proxy_redirect off;
}
}
$ systemctl reload nginx
$ systemctl restart nginx.service
그러면 Nginx IP주소에서 새로고침할때마다 각 서버로 로드밸런싱되는 것을 확인할 수 있습니다.
'Spring > 트러블 슈팅' 카테고리의 다른 글
쿼리 최적화를 했지만 부족하다면, Parallel Stream으로 성능 개선하기 (0) | 2024.04.29 |
---|---|
ResponseEntity vs @ResponseStatus 차이와 동시 사용 시 발생할 문제점 (0) | 2024.04.15 |
비동기 쿠폰 발급 알림 기능에서 SSE를 선택한 이유 (0) | 2024.03.25 |
@UtilityClass란? (0) | 2024.03.25 |
트러블 슈팅 - 테스트코드도 코드이므로 합성을 통해 중복을 없애자 (0) | 2024.03.16 |