어떻게 하면 잘 정리했다고 소문이 날까...

[요저개 3편] 웹서버와 웹 어플리케이션 서버 본문

요것저것 개발 지식쌓기😎/요저개 시리즈

[요저개 3편] 웹서버와 웹 어플리케이션 서버

정리왕이되자 2023. 7. 20. 15:13

👋🏻  Introduction

오늘은 웹 서버(WS)와 웹 어플리케이션 서버(WAS)의 차이에 대해 정리해보고자 합니다.

그리고 실제로 서비스를 배포할 때 사용하는 웹 서버인 Nginx에 대해서도 알아보고자 합니다.

이후에 AWS EC2와 RDS를 활용해 Django로 개발된 서비스를 uWSGI와 Nginx를 사용해 배포하는 과정도 정리해보려 합니다.

우선, 배포에 들어가기 전에 웹 서버와 웹 어플리케이션이 무슨일을 하는 지 알아볼까요?

 

🧐 웹서버와 웹 어플리케이션 서버의 차이

  1. 응답과 요청
    • 웹 서비스에 무엇을 요청하고 무엇을 응답하는가?
      • 웹 페이지를 요청하고 이를 응답한다. 웹 페이지는 크게 2가지로 나눌 수 있다.
      • 정적 페이지: 사용자의 요청에 관계 없이 동일한 페이지.
      • 동적 페이지: 요청에 맞는 데이터를 반환하는 페이지.
      • 좀 더 쉽게 이해하자면, 정적 페이지는 웹 어플리케이션 서버의 처리가 필요없는 요소다. 예를 들면, 네이버의 로고 같은것 .
      • 동적 페이지는 웹 어플리케이션 서버의 처리가 필요한 요소이다.
  2. Web Server와 Web Application Server
    • Web Server는 정적 페이지 반환.
    • Web Application Server는 동적 페이지 모두 반환. WAS는 동적페이지까지 반환이 가능한 WS.
    • 그렇다면 궁금증이 생긴다!  WAS는 두 페이지를 모두 반환할 수 있는데, 왜 서비스 배포할 때 WS도 같이 배포할까?
      • 더 빠르게 많은 요청을 처리하기 위해서!
      • 각자 잘하는 것을 하게 해 효율을 높이는 것이 목표.
      • 이외에도, 보안과 구조적 유연성, 운영과 같은 이유.
        • 보안: SSL 암호화와 복호화에 WS를 사용함.
        • 구조적 유연성: 하나의 웹 서버를 두고 여러 개의 웹 어플리케이션 사용 가능. 웹 서버는 일종의 라우터 역할.
        • 운영: 로드밸런싱, 장애극복, 무중단 운영.
  3. 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로 연결되도록 설정하면 됨.
  • 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;

 

참고:  https://cholol.tistory.com/485