Notice
Recent Posts
Recent Comments
Link
어떻게 하면 잘 정리했다고 소문이 날까...
[요저개 3편] 웹서버와 웹 어플리케이션 서버 본문
👋🏻 Introduction
오늘은 웹 서버(WS)와 웹 어플리케이션 서버(WAS)의 차이에 대해 정리해보고자 합니다.
그리고 실제로 서비스를 배포할 때 사용하는 웹 서버인 Nginx에 대해서도 알아보고자 합니다.
이후에 AWS EC2와 RDS를 활용해 Django로 개발된 서비스를 uWSGI와 Nginx를 사용해 배포하는 과정도 정리해보려 합니다.
우선, 배포에 들어가기 전에 웹 서버와 웹 어플리케이션이 무슨일을 하는 지 알아볼까요?
🧐 웹서버와 웹 어플리케이션 서버의 차이
- 응답과 요청
- 웹 서비스에 무엇을 요청하고 무엇을 응답하는가?
- 웹 페이지를 요청하고 이를 응답한다. 웹 페이지는 크게 2가지로 나눌 수 있다.
- 정적 페이지: 사용자의 요청에 관계 없이 동일한 페이지.
- 동적 페이지: 요청에 맞는 데이터를 반환하는 페이지.
- 좀 더 쉽게 이해하자면, 정적 페이지는 웹 어플리케이션 서버의 처리가 필요없는 요소다. 예를 들면, 네이버의 로고 같은것 .
- 동적 페이지는 웹 어플리케이션 서버의 처리가 필요한 요소이다.
- 웹 서비스에 무엇을 요청하고 무엇을 응답하는가?
- Web Server와 Web Application Server
- Web Server는 정적 페이지 반환.
- Web Application Server는 동적 페이지 모두 반환. WAS는 동적페이지까지 반환이 가능한 WS.
- 그렇다면 궁금증이 생긴다! WAS는 두 페이지를 모두 반환할 수 있는데, 왜 서비스 배포할 때 WS도 같이 배포할까?
- 더 빠르게 많은 요청을 처리하기 위해서!
- 각자 잘하는 것을 하게 해 효율을 높이는 것이 목표.
- 이외에도, 보안과 구조적 유연성, 운영과 같은 이유.
- 보안: SSL 암호화와 복호화에 WS를 사용함.
- 구조적 유연성: 하나의 웹 서버를 두고 여러 개의 웹 어플리케이션 사용 가능. 웹 서버는 일종의 라우터 역할.
- 운영: 로드밸런싱, 장애극복, 무중단 운영.
- Django와 WebServer
- 파이썬은 GIL(Global Interpreter Lock)
- 동시에 하나의 스레드만 실행 가능.
- 그러므로 웹 서버가 필요함.
- 웹서버로 아파치와 Nginx가 주로 사용됨.
- 아파치: prefork(요청마다 프로세스가 생성)과 worker(요청마다 스레드 생성) 방식.
- Nginx: 이벤트 드리븐 방식으로 모든 커넥션을 비동기 방식으로 처리.
🧐 uWSGI와 Nginx
- 저는 주로 Django를 활용한 서비스를 배포하였는데, 서비스 배포 시 웹서버로는 Nginx를 웹 서버와 웹 어플리케이션 서버인 Django 사이의 연결을 위해 uWSGI를 사용하였습니다.
- WSGI(Web Server Gateway Interface)
- CGI: Common Gateway Interface
- 웹 서버와 웹 어플리케이션 사이의 인터페이스 제공.
- 하나의 규약을 제공하여 다른 프레임워크를 사용하게 되더라도 연결에 불편이 없게 함.
- 연결만 도와주는 것이 아닌 프로세스/스레드에 대해 설정 및 멀티 스레드, 서버가 죽었을 때 다시 시작하는 환경 제공.
- wsgi는 ssl과 정적 파일 지원을 하지 않지만, uWSGI는 지원함. 그렇지만 자원을 많이 사용.
- uWSGI는 유닉스 소켓을 지원함.
- uWSGI
- nginx도 유닉스 소켓 연결을 지원하고 uWSGI도 유닉스 소켓 연결을 지원하기 때문에 더 빠르고 안전하게 서비스를 제공.
- HTTP 통신도 가능하지만 같은 서버 내에 있기 때문에 유닉스 소켓으로 통신하는 것이 오버헤드가 적어 효율적.
- Nginx
- 트래픽이 많은 웹 사이트 서버(WAS)를 도와주는 비동기 이벤트 기반 구조의 경량화 웹 서버 프로그램.
- 클라이언트로부터 요청을 받았을 때 요청에 맞는 정적 파일을 응답하는 HTTP Web Server로 활용되기도 하고, Reverse Proxy Server로 활용해 WAS의 부하를 줄이는 로드 밸런서의 역할을 하기도 함.
- 정리
- 하나의 스레드 내에 여러 개의 요청을 처리하는 Event-Driven 방식으로 동작.
- 한 개 또는 고정된 프로세스만 생성하고, 그 내부에서 비동기 효율적인 방식으로 task 처리.
- 하나의 스레드가 하나의 요청을 처리하는 프로세스 기반 접근 방식인 Apache와 달리 동시 접속자 수가 많아져도 추가적인 생성 비용이 들지 않음.
- 비동기 이벤트 기반으로 요청해 적은 양의 스레드가 사용되기 때문에 CPU 소모가 적다.
- Apache와 달리 CPU 관계 없이 I/O를 전부 Event Listener에 미루기 때문에 흐름이 끊이지 않는다.
- Context-Switching 비용이 적다.
🧐 Nginx 실습
- nginx 설치
- sudo apt-get install nginx
- nginx 설정
- /etc/nginx/nginx.conf 파일 열어보기.
- sites-availabled/는 nginx에서 관리되는 호스트의 정보. 비활성화된 사잍,
- sites-enabled/에 sites-availabled/를 추가해야 활성화됨. 심볼릭 링크를 해서 활성화 가능.
- 기본으로 설정된 default 파일은 삭제하기. sites-enabled/default
- nginx.conf 구성
- Core 모듈
- user: nginx 프로세스가 실행되는 계정.
- worker_process: nginx 프로세스가 실행되는 수. auto로 설정하면 서버의 cpu 수.
- pid: nginx 프로세스들의 pid를 모아두는 파일 생성 설정.
- include: 특정 경로에 있는 .conf 파일들을 읽어온다. 설정 파일을 나누어 관리할 수 있도록 한다.
- event 블록
- worker_connections: 하나의 worker 프로세스가 처리할 수 있는 커넥션의 수. nginx는 비동기 처리하기에 프로세스 하나에 다수의 커넥션 존재.
- multi-accept: nginx가 동시에 커넥션을 받을 지 정하는 config. 기본 값은 off인데, off의 경우 한 번에 하나의 connection을 생성해서 worker_connections에 설정된 수만큼 생성하는 것이고, multi-accept가 on인 경우 한 번에 50개 혹은 100개씩 커넥션 생성 가능. 이렇게 한번에 들어오는 connection이 worker_connections보다 많으면 에러 발생 가능.
- http 블록
- sendfile: 응답을 보낼 때, read와 write을 하게 되는데 사용자 영역에서 파일을 읽고 쓰는 것이 아닌 커널 영역의 buffer를 사용해 속도를 향상하는 옵션.
- tcp_nopush: sendfile이 on일 때만 사용하는 옵션으로, TCP_CORK 옵션을 사용해 통신. TCP_CORK란 쉽게 설명하면 네트워크 통신에서 패킷을 여러 개 보내지않고, 한번에 보내서 통신 속도를 향상하는 방법. 왜 여러번 보내는 것보다 한번에 보내는 것이 좋은가 하면 패킷을 보낼 때 마다 헤더가 패킷 앞에 붙기 마련인데, 여러 번 보내면 헤더가 많이 보내지기 때문이다.
- tcp_nodelay: tcp_nopush와 반대. 아무리 작은 패킷이라도 바로바로 전송하는 옵션. keepalive_timeout 옵션이 on이어야 사용 가능.
- keepalive_timeout: 응답을 보내고 얼마나 커넥션을 유지할 것인지 설정하는 옵션. 여러 번 통신을 하는 거면 커넥션을 맺는 일 조차 낭비이기 때문에 옵션을 켜는 것이 좋고, 단일로 발생한다면 끄는 것이 좋다. 켜져 있으면 커넥션이 그만큼 살아있기 때문에 리소스를 잡아먹음.
- ssl_protocols: ssl 프로토콜을 어떤 것을 사용할지 명시. 거의 거드는 일이 없다고 함.
- 맨 아래에 virtual host configs가 있는데 호스트의 설정값들이 저장된 폴더를 include합니다. conf.d에는 아무것도 없고, sites-enabled 폴더에는 default가 있는데, 이 default를 지우고 uwsgi로 연결되도록 설정하면 됨.
- Core 모듈
- virutal host config 설정 - /etc/nginx/sites-enabled
- upstream 서버 이름
- 서버 그룹을 정의하는 곳. server 주소 or 소켓 으로 서버 목록 나열.
- server
- 서버에 대한 상세 정의.
- listen으로 포트 적고.
- server_name localhost
- charset utf-8
- client_max_body_size 크기 : 요청이 올라올 때 최대 크기 정하기
- location은 위치 잡아줌.
- uwsgi_pass 서버이름
- include uwsgi_params;
- upstream 서버 이름
'요것저것 개발 지식쌓기😎 > 요저개 시리즈' 카테고리의 다른 글
[요저개 6편] Open AI API 활용하기 - DallE 3편 (3) | 2024.03.05 |
---|---|
[요저개 4편] REST API (0) | 2023.07.21 |
[요저개 2편] JWT(Json Web Token) (1) | 2023.05.16 |
[요저개 1편] 마이크로서비스 아키텍처(MSA) (0) | 2023.05.03 |