본문 바로가기

서버운영 (TA, ADMIN)/미들웨어

[Nginx] 엔진엑스 프록시 모듈

엔진엑스 기본 빌드에는 프록시 모듈이 포함돼 있어 클라이언트로부터의 HTTP 요청을 백엔드 서버에 전달합니다. 여러 관점에서 모듈환경을 설정해봅시다.


 - 백엔드 서버의 기본 주소와 포트 정보

 - 캐싱, 버퍼링, 임시 파일 옵션

 - 한계치, 제한시간, 에러 처리


주요 지시어


이 부류의 지시어는 백엔드 서버의 위치, 전달되는 정보, 전달 방법 등과 같은 기본 환경을 설정합니다.


1. proxy_pass (문맥: location, if)

자신의 위치를 표시함으로써 요청이 백엔드 서버로 전달되게 지정합니다.


# TCP 소켓을 사용할 때의 구문

proxy_pass http://hostname:port;


# 유닉스 도메인 소켓을 사용할 때의 구문

proxy_pass http://unx:/path/to/file.socket;


# 업스트림 블록을 사용해도 좋다.

proxy_pass http://myblock;


# 보안 통신용으로 http:// 대신에 https:// 를 사용할 수 있다.

# 변수뿐만 아니라 추가적인 URI 부분을 사용해도 좋다.


proxy_pass http://localhost:8080;

proxy_pass http://127.0.0.1:8080;

proxy_pass http://unix:/tmp/nginx.sock;

proxy_pass https://192.168.0.1;

proxy_pass http://localhost:8080/uri/;

proxy_pass http://unix:/tmp/nginx.sock:/uri/;

proxy_pass http://$server_name:8080;


# 업스트림 블록을 사용

upstream backend {

server 127.0.0.1:8080;

server 127.0.0.1:8181;

}

location ~* \.php$ {

proxy_pass http://backend;

}




2. proxy_method (문맥: http, server, location)

백엔드 서버에 전달되는 요청의 HTTP 메소드를 덮어 쓰기할 수 있습니다. 예를 들어 POST를 지정하면 백엔드 서버로 전다로디는 모든 요청은 POST 요청으로 바뀝니다.


proxy_method POST;



3. proxy_hide_header (문맥: http, server, location)

엔진엑스는 백엔드 서버로부터 수신된 응답을 처리해 클라이언트에 전달하기 때문에 기본적으로 Date, Server, X-Pad, X-Accel-* 같은 일부 헤드를 무시합니다. 이 지시어를 사용하면 클라이언트에게 숨길 헤더를 추가할 수 있습니다. 이 지시어는 각 줄마다 헤더 이름을 갖게 해 여러번 삽입 가능합니다.


proxy_hide_header Cache-Control;



4. proxy_pass_header (문맥: http, server, location)

앞의 지시어와 연관해 이 지시어는 무시된 헤더의 일부를 클라이언트에게 전달합니다.


proxy_pass_header Date;



5. proxy_pass_request_body, proxy_pass_request_headers (문맥: http, server, location)

요청 바디와 추가 요청 헤더를 각기 백엔드 서버에 전달할지 여부를 정의합니다.



6. proxy_redirect (문맥: http, server, location)

백엔드 서버에 의해 촉발된 리다이렉션에 대해 로케이션 HTTP 헤더에 나타나는 URL을 재작성합니다.


off: 리다이렉션은 설정된 그대로 전달된다.

default: 호스트명과 현재 문서 경로가 첨부된 proxy_pass 지시어 값이 사용된다. 환경설정은 순차적으로 파싱되므로 proxy_redirect 지시어는 proxy_pass 지시어 다음에 삽입해야 함에 유의한다.

URL: URL의 일부를 다른 것으로 바꾼다.

또한 재작성 URL 안에 변수를 사용해도 좋다.


proxy_redirect off;

proxy_redirect default;

proxy_redirect http://localhost:8080/ http://example.com/;

proxy_redirect http://localhost:8080/wiki/ /w/;

proxy_redirect http://localhots:8080/ http://$host/;



7. proxy_next_upstream (문맥: http, server, location)

proxy_pass가 업슽트림 블록에 연결될 때 이 지시어는 요청을 포기하고 그 블록의 다음 업스트림 서버로 다시 전송되는 경우를 정의합니다. 지시어 값으로 다음의 값들을 조합해 사용할 수 있습니다.


error: 서버와 통신을 하거나 통신을 시도하는 도중에 에러가 발생했다.

timeout: 전송 중이거나 접속을 시도하는 동안 제한시간 초과가 발생했다.

invalid_header: 백엔드 서버가 빈 응답이나 유효하지 않은 응답을 회신했다.

http_500, http_502, http_503, http_504, http_404: 해당 HTTP 에러가 발생하면 엔진엑스는 다음 업스트림으로 전환된다.

off: 다음 업스트림 서버를 사용하지 못하게 금지한다.


proxy_next_upstream error timeout http_504;

proxy_next_upstream timeout invalid_header;




캐싱, 버퍼링, 임시 파일


백엔드 서버로 전달하는 요청 수는 최대한 줄이는 것이 이상적입니다. 다음 지시어들은 제어 버퍼링 옵션, 엔진엑스가 임시 파일을 다루는 방식뿐만 아니라 캐싱 시스템을 만드는 것을 돕습니다.


1. proxy_buffer_size (문맥: http, server, location)

백엔드 서버 응답의 첫 부분을 읽기 위한 버퍼 크기를 설정하며, 여기에는 주로 간단한 헤더 데이터가 포함됩니다.


proxy_buffer_size 4k;



2. proxy_buffering (문맥: http, server ,location)

백엔드 서버로부터의 응답을 버퍼링할지 여부를 정의합니다. on으로 설정하면 엔진엑스는 버퍼가 제공하는 메모리 공간을 이용해 응답 데이터를 메모리에 저장합니다. 버퍼가 꽉 차면 응답 데이터는 임시 파일에 저장됩니다. 이 지시어를 off로 설정하면 응답을 직접 클라이언트에게 전달합니다.



3. proxy_buffers (문맥: http, server, location)

백엔드 서버로부터의 응답 데이터를 읽는 데 사용할 버퍼의 수와 크기를 설정합니다.


proxy_buffers 8 4k;



4. proxy_busy_buffers_size (문맥: http, server, location)

백엔드에서 수신되는 데이터가 버퍼에 쌓이다가 이 지시어로 지정한 값을 초과하면 데이터를 클라이언트로 보내고 버퍼를 비웁니다.


2*proxy_buffer_size



5. proxy_cache (문맥: http, server, location)

캐시 존을 정의합니다. 캐시 존에 부여된 식별자를 이용해 이후의 다른 지시어에서 재사용할 수 있습니다.


proxy_cache cache1;



6. proxy_cache_key (문맥: http, server, location)

이 지시어는 캐시 항목들을 서로 구분하는 캐시 키(cache key)를 정의합니다. 캐시 키가 $uri로 설정돼 있으면 $uri가 같은 모든 요청은 같은 캐시 항목으로 대응됩니다. 대부분의 동적 사이트에서는 그 정도로는 충분하지 않으므로 /index.php와 index.php?page=contact가 같은 캐시 항목을 가리키지 않게 캐시키에 질의문자열 인자를 포함할 필요가 있습니다.


proxy_cache_key key;

proxy_cache_key "$scheme$host$request_uri$cookie_user";



7. proxy_cache_path

캐시된 파일과 매개변수를 저장하기 위한 디렉토리를 지정합니다.


proxy_cache_path path [levels=numbers keys_zone=name:size inactive=time max_size=size];


 - levels: 하위 디렉토리의 깊이를 나타낸다(보통은 1:2 정도면 충분)

 - keys_zone: 앞서 proxy_cache 지시어로 선언한 캐시 존을 이용할 수 있게 하며, 차지하는 메모리 크기를 나타낸다.

 - inactive: 캐시된 응답이 지정한 시간만큼 사용되지 않으면 캐시로부터 제거된다.

 - max_size: 전체 캐시의 최대 크기를 정의한다.


proxy_cache_path /tmp/nginx_cache levels=1:2 zone=zone1:10m inactive=10m max_size=200M;



8. proxy_cache_methods (문맥: http, server, location)

캐시가 적용되는 HTTP 메소드를 정의합니다. GET과 HEAD는 기본으로 포함되며 캐싱을 해제할 수 없습니다. 예를 들어 POST 요청을 캐싱하게 설정할 수 있습니다.


proxy_cache_methods POST;



9. proxy_cache_min_uses (문맥: http, server, location)

요청이 캐시되는 데 필요한 최소 히트 수를 정의합니다. 기본으로 요청의 응답은 한 번의 히트 후에 캐시됩니다.(같은 캐시 키를 갖은 이후의 요청은 캐시된 응답을 수신하게 됩니다.)


proxy_cache_min_uses 1;



10. proxy_cache_valid (문맥: http, server, location)

이 지시어는 여러 종류의 응답 코드에 대해 각 캐시 시간을 지정합니다. 404 에러 코드와 연관된 응답은 1분 동안 캐시하고 반대로 200 OK 응답은 10분 이상 캐시할 수 있습니다. 이 지시어는 한 번 이상 사용할 수 있습니다.


proxy_cache_valid 404 1m;

proxy_cache_valid 500 502 504 5m;

proxy_cache_valid 200 10;



11. proxy_cache_use_stale (문맥: http, server, location)

게이트웨이와 관련된 특정 상황에서 오래된 캐시 데이터를 사용할지 여부를 정의합니다. proxy_cache_use_stale timeout을 사용하면 게이트웨이가 ㅅ제한 시간을 초과했을 때 엔진엑스는 캐시된 데이터로 서비스합니다.


proxy_cache_use_stale [updating] [errors] [timeout] [invalid_header] [http_500];

proxy_cache_use_stale error timeout;




한계치, 제한시간, 에러


다음 지시어들은 백엔드 서버와의 통신에 관련된 여러 가지 제약 사항과 시간 초과시에 시스템 동작을 정의하는데 사용합니다.


1. proxy_connect_timeout (문맥: http, server, location)

백엔드 서버 접속 제한시간을 정의합니다. 이 값은 읽기/쓰기 시간 초과와는 다릅니다. 즉, 엔진엑스가 이미 백엔드 서버에 접속된 상태라면 proxy_connect_timeout은 적용될 수  없습니다.


proxy_connect_timeout 15;


2. proxy_read_timeout (문맥: http, server, location)

백엔드 서버로부터 데이터를 읽을 때의 제한시간으로, 이 제한시간은 전체 응답 지연 시간에 적용되는 것이 아니라 두 개의 읽기 작업 사이에 적용됩니다.


proxy_read_timeout 60;


3. proxy_send_timeout (문맥: http, server, location)

백엔드 서버로 데이터를 전송할 때의 제한시간으로, 이 제한시간은 전체 응답 지연 시간에 적용되는 것이 아니라 두 개의 쓰기 작업 사이에 적용 됩니다.


proxy_send_timeout 60;


4. proxy_ignore_client_abort (문맥: http, server, location)

이 지시어 값을 on으로 설정하면 클라이언트가 요청을 중지시켜도 계속해서 프록시 요청을 처리합니다. off로 설정하면 클라이언트가 요청을 중지시킬 때 엔진엑스도 백엔드 서버에 요청하는 것을 중지합니다.


5. proxy_intercept_errors (문맥: http, server, location)

기본적으로는 백엔드 서버가 보내오는 모든 에러 페이지를 엔진엑스가 직접 클라이언트에게 회신합니다. 이 지시어 값을 on으로 설정하면 에러 코드를 분석해 error_page 지시어에서 지정한 값과 비교 합니다.



변수


프록시 모듈은 다양한 위치에서 활용되는 여러 가지 변수를 제공합니다. 예를 들면 proxy_set_header 지시어나 log_format 같은 로그 관련 지시어에서 변수를 사용할 수 있습니다. 프록시 모듈 변수에는 다음과 같은 것이 있습니다.


$proxy_host    현재 요청에 사용된 백엔드 서버의 호스트명을 포함

$proxy_port    현재 요청에 사용된 백엔드 서버의 포트 번호를 포함

$proxy_add_x_forwarded_for    이 변수는 X-Forwarded-For 요청 헤더와 그 뒤에 따라오는 클라이언트의 원격 주소를 포함한다. 두 값은 콤마로 분리된다. X-Forwarded-For 요청 헤더가 없으면 클라이언트 원격 주소만 포함된다.

$proxy_internal_body_length    요청 바디의 길이로, proxy_set_body 지시어에 의해 설정하거나 0값을 갖는다.






"아파치는 마이크로소프트 워드 같다. 수백만개의 옵션이 있지만 사람들은 단지 여섯개만 사용한다. 그 여섯 개의 옵션은 엔진엑스에도 있고, 그 중 다섯 개는 아파치보다 50배나 빠르다" - 크리스 리


"나는 현재 단 한 개의 서버로 하루에 수천만 개 이상의 HTTP 요청(초당 수백 개)을 처리하는 리버스 프록시로서 엔진엑스를 사용 중이다. 나의 특별한 환경 설정(FreeBST 6)에서 부하가 최대로 걸렸을때 약 15MB의 RAM과 10%의 CPU를 사용한다. 똑같은 부하가 걸렸을 때 아파치는 약 1,000개의 프로세스와 하나님만 알 수 있을 정도로 많은 RAM을 사용한 후 멈춰버린다. Pound는 지차니첵 많은 스레드와 스레드 스택용 RAM을 400MB 이상이나 사용한 후에 멈춰버리고, Lighty는 심각할 정도는 아니지만 더 많은 CPU를 사용하면서 시간당 20MB이상 새어나간다" - 밥 이폴리토


사용할 수 있는 자원에 한계가 있는 상황에서 대규모 프로젝트 시장에 나와있다면 엔진엑스야말로 훌륭한 솔루션이 됩니다. 아파치는 웹서버와 호스팅에 관한 지식이 한정돼 있을때 프로젝트를 시작하기에 좋은 옵션이지만, 목적이 달성되고 나면 얼마 되지 않아 관리자와 서버와 방문자는 서비스에 일관성이 없음을 결국 깨닫게 됩니다.