DevOps

Nginx로 서버와 클라이언트 중개하기

soohey 2022. 7. 28. 23:30

Nginx란?

1. HTTP 서버로서 정적 파일을 serve해줌

  • 클라이언트로부터 요청을 받았을 때 WAS를 거치지 않고 요청에 맞는 정적파일을 응답해주는 HTTP server로서 활용할 수 있다.
  • HTML, CSS같은 정적인 리소스에 대한 요청을 Nginx가 처리해준다.
  • React의 빌드된 파일들도 정적인 리소스라고 볼 수 있고 따라서 nginx가 index.html같은 메인 페이지를 랜더링할 수 있다.

2. Reverse Proxy Server로서 클라이언트와 서버를 중개해줌

  • 클라이언트의 request와 서버의 response를 중개하는 서버로 동작할 수 있다.
  • 이 과정에서 nginx는 로드밸런서로서의 역할을 수행
  • 동적으로 계산되거나 전달되어야 하는 사항은 WAS에게 맡김

WAS

  • 웹서버로부터 오는 동적인 요청들을 처리하는 서버
  • 흔히 사용하는 웹 프레임워크를 사용해 구축하는 백엔드를 WAS라고 생각하면 됨. 주로 데이터베이스 서버와 같이 관리됨

Django와 WSGI, Gunicorn

  • Django가 클라이언트의 요청을 웹서버를 통해 받을 때 WSGI라는 것을 반드시 거치게 됨
  • WSGI(web server gateway interface)는 이름만 봐도 웹에 대한 인터페이스임
  • 오직 파이썬을 위한 인터페이스
  • 웹 서버에서 전달해주는 HttpRequest를 파이썬이 이해할 수 있는 언어로 해석해서 파이썬 프로그램으로 보내주는 역할을 맡게 된다.
  • Django는 python으로 만들어진 프레임워크이므로 쟝고와 웹서버를 결합하기 위해선 WSGI가 필요함
  • Django에는 런서버라고 불리는 개발환경에 적합한 서버를 돌릴 수 있는 기능이 있음. 하지만 런서버는 단일 스레드로 동작하기 때문에 요청이 많아지면 처리능력이 현저히 떨어지는 단점때문에 실제 배포환경에서는 사용해서는 안되는 방법임. 그래서 WSGI를 사용함
  • WSGI는 멀티 스레드를 생성할 수 있기 때문에 요청이 많아져도 안정적으로 처리가 가능하다. WSGI의 종류에는 uwsgi, Gunicorn이 양대산맥으로 있지만 최근 Gunicorn의 성능이 uwsgi보다 좋아져서 대부분 구니콘 사용

 

Gunicorn을 Django의 WSGI로 사용하고 Django와 Gunicorn을 합쳐 WAS라고 한다.

 

Nginx와 관련된 개념

Proxy

  • 클라이언트가 데이터를 요청하면 서버가 요청한 리소스를 가져다 준다.
  • 중간에 클라이언트의 요청을 서버로 보내주는 프록시라고 불리는 서버가 하나 존재함
  • 프록시는 중계서버라고 할 수 있음.
  • 클라이언트와 서버가 서로 직접적으로 통신하지 않고, 프록시서버를 이용해 리소스를 전달하며 보안, 트래픽 분산, 캐시사용(속도향상)등 여러 장점을 가지는 중요한 서버

Foward Proxy

  • 일반적인 프록시 서버
  • 클라이언트와 웹 서버의 중개역할로 클라이언트가 요청시 프록시 서버는 해당 요청을 웹서버로 중계해 자원을 가져오는 개념
  • 프록시 서버는 클라이언트가 요청하기 전까지 웹 서버의 주소를 알 수없다
  • 예를들어 회사 내부망에서 www.google.com으로 연결해 달라고 서버에 요청을 보내면 이때 프록시 서버를 호출하게 됨. 이것이 바로 프록시 방식
  • 주로 정해진 사이트에만 연결이 가능하도록 해서 회사 내부 인트라넷등 보안이 중요한 환경에서 사용

Reverse Proxy

  • 클라이언트와 서버사이에 위치해 보안, 로드밸런싱 역할
  • 클라이언트가 특정 리소스를 요청시 프록시 서버가 WAS에 요청 후 응답받은 리소스를 클라이언트에게 전달
  • 특정 ip주소에서 제공하는 api서버를 호출하기 위해 인터넷에 있는 클라이언트가 리버스 프록시 서버에 api를 요청해서 응답을 받는 방식

로드밸런싱?

  • 서버의 부하를 분산시키는 기술
  • 많은 클라이언트들이 하나의 웹사이트에 접속해서 해당 서버의 트래픽이 늘어날 때 여러대의 서버를 이용해 요청을 처리하도록 한다.
  • 각 서버의 부하량, 속도 저하등을 고려해서 서버의 가중치, 스케줄링등을 결정해 트래픽을 적절히 분산시키는 과정

로드밸런싱의 장점

  • 한 서버의 부하를 분산시킴
  • 값싼 비용으로 다수 서버를 증설해 관리가능 -> 고가의 서버 필요 x
  • 1대의 서버가 멈춰도 서비스가 중단되지 않음. 마찬가지로 서버를 늘리는 과정에도 서비스 중단 x

Nginx에서 제공하는 로드밸런싱 방법 3가지

  1. 라운드 로빈 : 운영체제 스케줄링 방법, 주어진 서버들을 순차적으로 돌아가며 선택하는 방식
  2. Least-connected : 현재 접속자 수가 가장 적은 서버를 선택
  3. Ip-hash : hash function을 사용해 클라이언트 ip를 hash한 결과에 따라 다른 서버에 할당

API

  • Application Programming Interface
  • 특정 서비스나 응용 프로그램에서 소스코드를 공개하지 않고 요청한 기능을 제공하기 위해 사용
  • 서버 api는 web 서버에 클라이언트가 어떤 요청을 했을 때 그에 맞는 응답을 줄 수 있는 endpoint를 웹을 통해 노출한 것
  • https://localhost:8080/sjlf 라는 endpoint에 서버와 연결된 데이터베이스에 있는 모든 회사의 주가정보를 json으로 반환하는 api를 열어놓았다면 사용자는 해당 endpoint를 요청해 데이터를 json으로 받아옴

API의 역할

  • 모든 사람들이 서비스의 고유 데이터베이스에 접근해서는 안됨
  • 이를 방지하기 위해 서버와 데이터베이스의 출입문 역할을 하며 허용된 클라이언트와 서버에 대해서만 데이터를 넘겨줌
  • Django-nginx로 서버를 구축했다면 리버스 프록시인 nginx가 요청할 때만 django는 데이터를 넘겨주도록 해야함
  • api는 모든 접속을 표준화하기 때문에 클라이언트/운영체제와 상관없이 누구나 동일한 데이터를 얻을 수 있게 한다.

REST API?

  • API의 endpoint 아키텍처 스타일
  • HTTP 메서드를 사용하면 진정한 RESTful API 라고 할 수 있음
  • REpresentational State Transfer
  • 리소스를 중심으로 디자인된다. 클라이언트에서 요구하는 모든 종류의 데이터, 서비스가 리소스에 포함된다.
  • 리소스마다 해당 리소스를 고유하게 식별할 수 있는 URI인 식별자가 존재한다.
  • REST API는 균일한 인터페이스를 사용하므로 클라이언트와 서버의 분리에 도움이 된다. 가장 일반적인 작업은 GET, POST, PUT, PATCH, DELETE
  • REST API를 사용하는 HTTP 요청은 독립적이어야 하고 임의의 순서로 발생할 수 있기에 요청 사이에 일시적으로 상태 정보를 유지할 수 없다.
  • 이러한 조건때문에 웹서비스의 확장성에 우수함
  • 클라이언트와 특정 서버사이의 연결 및 선호도를 유지하지 않아도 됨
  • 따라서 모든 서버는 모든 클라이언트의 모든 요청을 처리할 수 있음
  • 리소스 중심의 API 디자인의 필요성
  • 동사(리소스 작업)이 아닌 명사(리소스)를 기반으로 URI 작성

 

요약

nginx는 서버와 클라이언트 사이의 중개인

또한 로드밸런싱의 역할을 하여 부하를 분산시켜줌