NGINX에 대해

Cramming An·2022년 3월 29일
0

FrontEnd

목록 보기
1/9
post-thumbnail

시작하기 앞서...

Nginx 라는 도구를 살펴보기 앞서, node.js 환경에서 어떤 식으로 웹서버를 만들었는지 기억을 되살려 봅시다.

웹서버

Client가 웹페이지에 접속하기 위해 반드시 필요한 서버입니다. Client는 HTTP 규격에 맞추어 웹페이지 구성에 필요한 파일들을 웹서버에 요청합니다. 웹서버는 요청된 파일들로 HTTP 규격에 맞추어 응답을 하고, 비로소 사용자는 웹페이지를 볼 수 있게 됩니다.

서버 만들기

기본적으로 node 런타임 환경에서 Express 같은 프레임워크를 사용한다면, 서버는 다음과 같은 방식으로 만들어집니다.

const app = express();

const handleListening = () => {
    console.log("Your server is listening!")
}

app.listen(PORT, handleListening);

하지만 원래 express 같은 프레임워크로 만들어진 서버는 데이터베이스와 연결되어 특별한 로직으로 데이터를 가공하여 동적인 컨텐츠를 제공하는 목적이 있지만, 웹 서버로써의 역할도 가능하고 지금까지 충분히 이를 이용해 로컬환경에서 웹서비스를 만들어왔습니다.

문제점

지금까지는 아무런 문제가 발생하지 않았다고 생각이 들지 모릅니다.
하지만 웹페이지를 사용하는 사람들의 수가 늘어난다면 어떻게 될까요?

사용자가 늘어나면 다음과 같은 문제점이 발생합니다.
1. 보안문제: 사용자가 증가함에 따라, 데이터 베이스와 직접 연결된 서버에 접속을 하게 되면 보안문제가 발생할 수 있습니다.
1. 서버의 수가 증가: 아무리 좋은 서버라도, 사용자의 수가 증가하면 모든 트래픽을 감당할 수 없게 됩니다. 따라서 서버를 추가로 구비하고 여러 대의 서버에 동일한 데이터를 저장해 수많은 트래픽을 분산하게 되는데, 이 때 Client가 오직 알고 있는 정보는 1개의 도메인이므로, 사용자를 분산시킬 수 없습니다.
2. CPU와 메모리 자원의 소모: 웹서버는 Client로부터 받은 요청을 처리할 때 새로운 프로세스 또는 쓰레드를 생성하여 처리합니다. 따라서 사용자가 늘면 요청 마다 쓰레드가 생성 되므로 그만큼 자원의 소모가 극심해 집니다.

NGINX (엔진 엑스)

함수, 포인터, React의 컴포넌트와 같이 많은 컴퓨터적인 문제 해결방식이 그렇듯, 이 문제도 중복의 경로를 하나로 합치는 방식으로, 다시 말해 Client와 서버 사이를 하나의 포인트로 묶어주는 무언가가 이 문제를 해결합니다.

해결방법

NGINX는 다음과 같은 방법으로 이 문제들을 해결합니다.
1. NGINX 리버스 프록시: 프록시는 일반적으로 서버 입장에서 Client가 누구인지 숨겨주는 역할을 합니다. 하지만 리버스 프록시는 반대로 Client 입장에서 서버가 누구인지 숨겨주는 역할을 합니다. 따라서 Client는 서버에 직접 접근을 하지 못하고, 반드시 NGINX를 거치게 됩니다. 이 때문에 서버는 외부로부터 보안상 유리해질 수 있습니다.
2. 로드밸런싱: 리버스 프록시에 알 수 있듯이 NGINX는 Client와 서버 사이의 중계 역할을 합니다. 따라서 Client의 요청들이 들어오면, 트래픽을 적절히 분산시켜 한번에 여러 서버에서 요청에 대한 처리가 가능합니다.
3. Nginx의 Event-Driven 구조: Nginx는 기본적으로 1개의 master process안에서 n개의 worker process가 작동하는 방식입니다. 실질적으로 모든 요청은 worker process가 처리하고, Nginx의 process들은 event-based model을 가지고 있습니다. 따라서 Client의 요청을 비동기적으로 처리해 쓰레드 방식 웹서버 보다 효율적인 자원사용이 가능합니다. 추가적으로 Nginx의 process들은 OS-dependent 하기 때문에 자동적으로, 설치된 하드웨어의 성능을 최대로 이용하게 됩니다.

NGINX 설정

Nginx를 설치했다면, Nginx를 어떤 서버에 연결하고 사용할 것인지에 대한 설정파일을 만들어주어야 합니다.
/etc/nginx/conf.d 디렉토리 안에 .conf 파일을 만들어 줍니다.

  1. 리버스 프록시:
# etc/nginx/conf.d/example.conf
server {
    # Nginx에 연결된 포트
    listen 80;
    listen [::]:80;
    
    # Nginx 웹서버 도메인
    server_name example.com; www.example.com # 가상 호스팅

    # example.com 접근
    location / {
	proxy_pass http://localhost:3000/; # 로컬 3000번 포트와 연결
	}
    # example.com/apple에 접근
    location /apple {
        proxy_pass http://localhost:4000/; # 로컬 4000번 포트와 연결
        }
}

※Nginx에 ssl 추가 가능

  • .conf 파일에 HTTPS 적용에 필요한 파일추가
  • HTTPS의 default 포트 443 사용
  • 80포트(HTTP)를 HTTPS로 리다이렉션
  1. 로드밸런싱:
http {
    upstream serverGroup {
        # 로드밸런싱 분배 방식 타이핑 가능 (least_conn, ip_hash ...)
        server localhost:3000;
        server localhost:3001;
        server localhost:3002;
    }

    server {
        listen 80;
        listen [::]:80;

        location / {
            proxy_pass http://serverGroup; # 여러개의 서버와 클라이언트 연결
        }
    }
}

Docker에서 NGINX 운영하기

  1. Nginx image 직접 빌드하거나 pull 하기
$ docker pull nginx
  1. 도커 컨테이너에서 로컬서버의 포트로 접근하는 법
server {
  listen 80;
  location / {
    proxy_pass http://host.docker.internal:4000; # http://host.docker.internal 이용하기
  }
}

Reference

profile
La Dolce Vita🥂

0개의 댓글