[NGINX] NGINX (1) - 웹 서버 설정 기초

늦잠·2024년 8월 11일
0

목표 : NGINX 설정 기초를 살펴보기.

(아래 글은 공식 문서와 다른 자료를 참고해 공부하면서 쓴 글이니 틀린 부분이 많을 수 있습니다.)

NGINX로 웹의 웹 서버를 구현해보자.

NGINX는 오픈소스 웹 서버 프로그램이다. 웹 서버란 클라이언트에게 웹 서비스를 제공해주는 소프트웨어이다.

웹 서버, WAS 등의 개념이 낯설다면 다음 영상을 참고할 것을 추천한다.
얄팍한 코딩 사전 - https://www.youtube.com/watch?v=Zimhvf2B7Es

웹서버 설정

NGINX를 설치해보기 전에 NGINX 설정 방법을 살펴보자. 설정에 따라 어떤 트래픽, 어떤 요청이 어디로 연결될지 결정할 수 있다.

Directives 지시어

NGINX의 설정은 directives(이하 지시어)와 지시어의 파라미터로 구성된다.

user www-data;
worker_processes auto;

지시어는 이렇게 한줄로 표현할 수도 있고,

events {
	worker_connections 768;
}

위처럼 블락(Block)으로 묶어서 표현할 수도 있다.

context

이 중 최상위 수준의 지시어를 context라 하며 트래픽 타입에 대해 설정한다. 종류는 다음과 같다.

  • events – 일반적인 커넥션 처리
  • http – HTTP 트래픽
  • mail – 메일 트래픽
  • stream – TCP, UDP 트래픽

위에 속하지 않은 바깥main context라 한다.

트래픽을 처리하는 각 컨텍스트에 server 블락을 추가하여 가상 서버를 정의할 수 있다. 여러 server 블락을 추가하는 것도 가능하다.

server

server {
    listen 127.0.0.1:8080;
    server_name example.org www.example.org;
}

위에서 말했듯이, server 지시어 블락에선 가상 서버를 정의한다.
NGINX는 요청이 도착했을 때 여러 가상 서버 중 요청을 처리할 가상 서버를 선택한다.

가상 서버는 어떤 식으로 선택되는지 아래에서 계속 확인해보자.

listen

server {
    listen 127.0.0.1:8080;
    # Additional server configuration
}

listen 지시어는 server 블락 내에서 요청을 수신할 IP 주소포트를 지정한다.
포트번호를 지정 안하면 표준 포트(보통 80)를, IP 주소를 지정 안하면 모든 IP를 수신한다.
listen 지시어 자체가 없으면 사용자 권리에 따라 특정 포트번호를 열어두게 된다.

server_name

server {
    listen      80;
    server_name example.org www.example.org;
    #...
}

server_name 지시어는 서버의 호스트 이름을 지정한다.
NGINX로 들어온 요청의 ip와 포트번호와 일치하는 서버가 있다면, 그 다음 server_name을 확인하게 된다. 요청의 Host 헤더를 확인해 저장되어 있는 서버 호스트 이름과 서버 블락의 server_name일치하는지 확인함.

일치하는 server_name을 가진 서버가 여러 개일 경우 다음 우선순위로 서버 이름을 선택한다.
1. 완전히 똑같은 서버 이름
2. 와일드 카드로 시작하는 서버 이름 중 가장 긴 서버 이름, ex) *.example.org
3. 와일드 카드로 끝나는 서버 이름 중 가장 긴 서버 이름, ex) mail.*
4. 일치하는 정규식 서버 이름 중 설정 파일에서 가장 먼저 나온 서버 이름.

server {
    listen 80 default_server;
    #...
}

일치하는 server_name이 없다면 요청이 도착한 포트의 default server로 요청을 보낸다.
default server는 위 예시처럼 listen 지시문의 파라미터로 지정된 서버이며, 그런 서버가 없다면 그냥 설정파일에서 가장 먼저 나온 서버가 default server가 된다.

location

location /some/path/ {
    #...
}

location 지시어는 server 블락 안에서 URI 기반으로 요청이 향할 곳을 나눈다. 당연히 한 server 블락 안에 여러 개의 location 블락이 있을 수 있으며, location 블락 안에도 location 블락이 들어갈 수 있다.

요약

요약하면 NGINX가 요청을 처리하는 과정은 다음과 같다.

  1. 트래픽 종류에 맞는 context가 처리를 맡는다.
  2. 그 context안에서 요청의 IP 주소와 포트에 맞는 server를 찾는다.
  3. 찾은 server가 여러 개라면 요청의 Host 헤더에 있는 서버 호스트 이름과 가장 잘 맞는 server_name이 있는 server를 선택한다.
  4. 요청의 URI에 따라 알맞는 listen 블락이 요청을 처리한다.

리버스 프록시

이 글의 목표는 NGINX를 웹 서버로서 사용하는 것이다. 이에 따라 NGINX는 주요 서버(이 경우엔 Spring Boot가 돌아가는 톰캣 서버)대리자로서, 요청을 주요 서버로 보내고, 응답을 받아와 클라이언트한테 보내게 된다.

이를 리버스 프록시(Reverse Proxy)라고 한다. NGINX의 리버스 프록시 기능을 설정해보자.

proxy_pass

location /some/path/ {
    proxy_pass http://www.example.com/link/;
}

요청을 주요 서버로 넘기기 위해 location 지시자 안에서 proxy_pass 지시자를 사용한다. 위 예시의 location 블락이 처리하는 모든 요청은 http://www.example.com/link/로 보내지게 된다.

이 과정에서 요청의 URI 중 location의 파라미터와 일치하는 부분은 proxy_pass의 파라미터로 교체된다.
ex)위 예시에서 /some/path/page.html의 경우,/some/path/부분이 교체되어 http://www.example.com/link/page.html로 연결된다.

(HTTP 서버가 아닌 서버로 요청을 넘기려면 proxy_pass가 아닌 다른 지시어를 사용해야한다. 그건 생략.)

헤더 편집

기본적으로 NGINX는 요청의 헤드 값 중 HostConnection 부분을 수정하고, 헤더에서 빈 값을 제거한다.
Host넘어가는 서버의 이름과 포트 값으로, Connectionclose 값으로 수정한다.

HTTP 헤더에서 -

  • Host : 요청하려는 서버 호스트 이름과 포트번호
  • Connection : 클라이언트와 서버의 연결방식 설정. keep-alive이면 연결이 끊어지지 않고 동일한 서버에 후속 요청을 보낼 수 있고, close면 요청 후 연결이 끊긴다.
location /some/path/ {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_pass http://localhost:8000;
}

이러한 헤더 세팅 설정은 proxy_set_header 지시어를 통해 수정할 수 있다.
위 예시에선 헤더의 Host$host 변수로 세팅한다.

버퍼 설정

디폴트로 NGINX는 서버로부터 응답을 받을 때 이를 버퍼링한다.
즉 서버로부터 응답을 전부 받을 때 까지 내부 버퍼에 저장해 두었다가 이를 한꺼번에 클라이언트에게 전달한다.

이는 클라이언트 속도가 느릴 때 최적화에 도움이 된다.
빠른 상호작용이 필요한 서비스의 경우엔 버퍼링을 끄고 응답속도를 높일 수도 있다.

location /some/path/ {
	proxy_buffering on;
    proxy_buffers 16 4k;
    proxy_buffer_size 2k;
    proxy_pass http://localhost:8000;
}

proxy_buffering는 버퍼링 기능을 on/off 하는 지시어로, on이 디폴트 값이다.
proxy_buffers버퍼의 개수와 크기를 정한다. 위 예시에선 4k크기의 버퍼를 16개 만들었다.
proxy_buffer_size첫 버퍼 한 개의 크기를 결정한다. 보통 응답의 맨 처음은 크기가 비교적 작은 헤더가 들어가기 때문에 더 작게 설정된다.


참고

profile
피카

0개의 댓글