웹사이트 검색

Nginx 구성 파일 구조 및 구성 컨텍스트 이해


소개

Nginx는 인터넷에서 가장 큰 일부 사이트의 부하를 처리하는 고성능 웹 서버입니다. 특히 많은 동시 연결을 처리하는 데 좋으며 정적 콘텐츠를 전달하거나 제공하는 데 탁월합니다. 이 가이드에서는 파일을 디자인하는 방법에 대한 몇 가지 지침과 함께 Nginx 구성 파일의 구조를 논의하는 데 중점을 둘 것입니다.

Nginx 구성 컨텍스트 이해

이 가이드는 기본 Nginx 구성 파일의 구조를 다룹니다. 이 파일의 위치는 Nginx 설치 방법에 따라 다릅니다. 많은 Linux 배포판에서 파일은 /etc/nginx/nginx.conf에 있습니다. 거기에 없으면 /usr/local/nginx/conf/nginx.conf 또는 /usr/local/etc/nginx/nginx.conf 에 있을 수도 있습니다. .

기본 구성 파일을 볼 때 가장 먼저 주목해야 할 사항 중 하나는 대괄호({} ) 세트로 표시된 트리와 같은 구조로 구성되어 있다는 것입니다. ). Nginx 문서에서 이러한 괄호로 정의된 영역은 관심 영역에 따라 분리된 구성 세부 정보를 포함하기 때문에 "컨텍스트\라고 합니다. 이러한 분할은 구성을 적용할지 여부를 결정하는 일부 조건 논리와 함께 조직 구조를 제공합니다. .

컨텍스트는 서로 계층화될 수 있으므로 Nginx는 구성 상속을 허용합니다. 일반적으로 지시문이 여러 중첩 범위에서 유효하면 더 넓은 컨텍스트의 선언이 모든 하위 컨텍스트에 기본값으로 전달됩니다. 자식 컨텍스트는 이러한 값을 재정의할 수 있습니다. 배열 유형 지시문에 대한 재정의는 이전 값을 추가하는 것이 아니라 대체한다는 점에 유의해야 합니다.

지시문은 설계된 컨텍스트에서만 사용할 수 있습니다. Nginx는 잘못된 컨텍스트에서 선언된 지시문이 있는 구성 파일을 읽을 때 오류를 발생시킵니다. Nginx 문서에는 각 지시문이 유효한 컨텍스트에 대한 정보가 포함되어 있어 유용한 참조가 됩니다.

아래에서는 Nginx로 작업할 때 접할 수 있는 가장 일반적인 컨텍스트에 대해 설명합니다.

핵심 컨텍스트

우리가 논의할 첫 번째 컨텍스트 그룹은 Nginx가 계층적 트리를 생성하고 개별 구성 블록을 분리하는 데 사용하는 핵심 컨텍스트입니다. Nginx 구성의 주요 구조를 구성하는 컨텍스트입니다.

주요 맥락

가장 일반적인 컨텍스트는 \main 또는 \global 컨텍스트입니다. 다음과 같은 일반적인 컨텍스트 블록에 포함되지 않은 유일한 컨텍스트입니다.

# The main context is here, outside any other contexts

. . .

context {

    . . .

}

이러한 블록 외부에 완전히 존재하는 모든 지시문은 "main\ 컨텍스트에 속합니다. Nginx 구성이 모듈 방식으로 설정된 경우(예: 여러 파일의 구성 옵션 포함) 일부 파일에는 나타나는 지침이 포함됩니다. 괄호로 묶인 컨텍스트 외부에 존재하지만 구성이 함께 로드되면 컨텍스트 내에 포함됩니다.

기본 컨텍스트는 Nginx 구성을 위한 가장 광범위한 환경을 나타냅니다. 전체 응용 프로그램에 영향을 미치는 세부 사항을 구성하는 데 사용됩니다. 이 섹션의 지시문은 하위 컨텍스트에 영향을 주지만 이들 중 많은 부분은 하위 수준에서 재정의할 수 없습니다.

기본 컨텍스트에서 구성되는 몇 가지 일반적인 세부 정보는 작업자 프로세스를 실행할 시스템 사용자 및 그룹, 작업자 수 및 기본 Nginx 프로세스의 ID를 저장하는 파일입니다. 전체 응용 프로그램에 대한 기본 오류 파일은 이 수준에서 설정할 수 있습니다(이는 보다 구체적인 컨텍스트에서 재정의될 수 있음).

이벤트 컨텍스트

"events\ 컨텍스트는 "main\ 컨텍스트 내에 포함됩니다. Nginx가 일반 수준에서 연결을 처리하는 방법에 영향을 미치는 전역 옵션을 설정하는 데 사용됩니다. Nginx 구성 내에서 정의된 단일 이벤트 컨텍스트만 있을 수 있습니다.

이 컨텍스트는 다른 괄호로 묶인 컨텍스트 외부의 구성 파일에서 다음과 같이 표시됩니다.

# main context

events {

    # events context
    . . .

}

Nginx는 이벤트 기반 연결 처리 모델을 사용하므로 이 컨텍스트 내에서 정의된 지시문은 작업자 프로세스가 연결을 처리하는 방법을 결정합니다. 주로 여기에 있는 지시문은 사용할 연결 처리 기술을 선택하거나 이러한 메서드가 구현되는 방식을 수정하는 데 사용됩니다.

일반적으로 연결 처리 방법은 플랫폼에서 사용할 수 있는 가장 효율적인 선택을 기반으로 자동으로 선택됩니다. Linux 시스템의 경우 일반적으로 epoll 방법이 최선의 선택입니다.

구성할 수 있는 다른 항목은 각 작업자가 처리할 수 있는 연결 수, 작업자가 한 번에 하나의 연결만 사용할지 또는 보류 중인 연결에 대한 알림을 받은 후 모든 보류 중인 연결을 사용할지 여부, 작업자가 이벤트에 교대로 응답할지 여부입니다. .

HTTP 컨텍스트

HTTP 컨텍스트 정의는 아마도 Nginx의 가장 일반적인 용도일 것입니다. Nginx를 웹 서버 또는 리버스 프록시로 구성할 때 "http\ 컨텍스트는 대부분의 구성을 보유합니다. 이 컨텍스트에는 프로그램이 HTTP 또는 HTTPS 연결을 처리하는 방법을 정의하는 데 필요한 모든 지시문 및 기타 컨텍스트가 포함됩니다.

http 컨텍스트는 이벤트 컨텍스트의 형제이므로 중첩되지 않고 나란히 나열되어야 합니다. 둘 다 기본 컨텍스트의 자식입니다.

# main context

events {
    # events context

    . . .

}

http {
    # http context

    . . .

}

하위 컨텍스트는 요청을 처리하는 방법에 대해 더 구체적이지만 이 수준의 지시문은 정의된 모든 가상 서버의 기본값을 제어합니다. 상속이 작동하는 방식에 따라 이 컨텍스트와 아래에서 많은 지시문을 구성할 수 있습니다.

접할 가능성이 있는 일부 지시문은 액세스 및 오류 로그(access_logerror_log)의 기본 위치를 제어하고 파일 작업을 위한 비동기 I/O를 구성합니다(aio, sendfiledirectio), 오류 발생 시 서버의 상태를 구성합니다(error_page). 기타 지시문은 압축 구성(gzipgzip_disable), TCP 연결 유지 설정 미세 조정(keepalive_disable, keepalive_requests) , keepalive_timeout), Nginx가 패킷 및 시스템 호출을 최적화하기 위해 따라야 할 규칙(sendfile, tcp_nodelay tcp_nopush). 추가 지시문은 응용 프로그램 수준 문서 루트 및 색인 파일(rootindex)을 구성하고 다양한 유형의 데이터를 저장하는 데 사용되는 다양한 해시 테이블( server_names, typesvariables의 경우 >*_hash_bucket_size*_hash_max_size). 자세한 내용은 Nginx 설명서를 참조하십시오.

서버 컨텍스트

\server 컨텍스트는 \http 컨텍스트 내에서 선언됩니다. 이것은 중첩된 괄호로 묶인 컨텍스트의 첫 번째 예입니다. 또한 다중 선언을 허용하는 첫 번째 컨텍스트이기도 합니다.

서버 컨텍스트의 일반적인 형식은 다음과 같습니다. 이들은 http 컨텍스트 내에 있음을 기억하십시오.

# main context

http {

    # http context

    server {

        # first server context

    }

    server {

        # second server context

    }

}

각 인스턴스는 클라이언트 요청을 처리할 특정 가상 서버를 정의하므로 여러 server 컨텍스트를 선언할 수 있습니다. 필요한 만큼의 서버 블록을 보유할 수 있으며 각 블록은 특정 연결 하위 집합을 처리할 수 있습니다.

이 컨텍스트 유형은 Nginx가 알고리즘을 선택하는 데 사용해야 하는 첫 번째 유형이기도 합니다. 각 클라이언트 요청은 단일 서버 컨텍스트에 정의된 구성에 따라 처리되므로 Nginx는 요청 세부 정보를 기반으로 가장 적합한 서버 컨텍스트를 결정해야 합니다. 도메인 이름 사용이 다른 두 가지 일반적인 옵션이 있습니다.

  • listen: 이 서버 블록이 응답하도록 설계된 IP 주소/포트 조합입니다. 클라이언트가 이러한 값과 일치하는 요청을 하면 연결을 처리하기 위해 이 블록이 잠재적으로 선택됩니다.
  • server_name: 이 지시문은 처리할 서버 블록을 선택하는 데 사용되는 다른 구성 요소입니다. 요청을 처리할 수 있는 동일한 특이성의 수신 지시문이 있는 서버 블록이 여러 개 있는 경우 Nginx는 요청의 "Host” 헤더를 구문 분석하고 이 지시문과 일치시킵니다.

이 컨텍스트의 지시문은 로깅, 문서 루트, 압축 등을 포함하여 http 컨텍스트에서 정의될 수 있는 많은 지시문을 재정의할 수 있습니다. http 컨텍스트에서 가져온 지시문 외에도 파일을 다음과 같이 구성할 수 있습니다. 요청에 응답(try_files), 리디렉션 및 재작성(return재작성), 임의 변수 설정(set).

위치 컨텍스트

정기적으로 다룰 다음 컨텍스트는 위치 컨텍스트입니다. 위치 컨텍스트는 서버 컨텍스트와 많은 관계 품질을 공유합니다. 예를 들어, 여러 위치 컨텍스트를 정의할 수 있고, 각 위치는 특정 유형의 클라이언트 요청을 처리하는 데 사용되며, 각 위치는 선택 알고리즘을 통해 클라이언트 요청에 대해 위치 정의를 일치시켜 선택됩니다.

서버 블록을 선택할지 여부를 결정하는 지시어는 서버 컨텍스트 내에서 정의되지만 요청을 처리하는 위치의 기능을 결정하는 구성 요소는 위치 정의에 있습니다. (위치 블록을 여는 줄).

일반적인 구문은 다음과 같습니다.

location match_modifier location_match {

    . . .

}

위치 블록은 서버 컨텍스트 내에 있으며 서버 블록과 달리 서로 중첩될 수 있습니다. 이는 트래픽의 특정 하위 집합을 파악하기 위해 보다 일반적인 위치 컨텍스트를 생성한 다음 내부에 추가 컨텍스트가 있는 보다 구체적인 기준에 따라 처리하는 데 유용할 수 있습니다.

# main context

server {
    
    # server context

    location /match/criteria {

        # first location context

    }

    location /other/criteria {

        # second location context

        location nested_match {

            # first nested location

        }

        location other_nested {

            # second nested location

        }

    }

}

서버 컨텍스트는 요청된 IP 주소/포트 조합과 "Host\ 헤더의 호스트 이름을 기반으로 선택되지만 위치 블록은 요청 URI를 확인하여 서버 블록 내에서 요청 처리를 더 나눕니다. 요청 URI는 도메인 이름 또는 IP 주소/포트 조합 뒤에 오는 요청 부분.

예를 들어 클라이언트가 포트 80에서 http://www.example.com/blog를 요청한다고 가정합니다. http, www.example.com 및 포트 80 구성 요소는 개별적으로 모두 선택할 서버 블록을 결정하는 데 사용됩니다. 서버가 선택된 후 /blog 부분(요청 URI)은 정의된 위치에 대해 평가되어 요청에 응답하는 데 사용할 추가 컨텍스트를 결정합니다.

위치 컨텍스트에서 볼 수 있는 많은 지시문은 상위 수준에서도 사용할 수 있습니다. 이 수준의 새 지시문을 사용하면 문서 루트 외부 위치(alias)에 도달하고 해당 위치를 내부적으로만 액세스할 수 있는 위치(internal)로 표시하고 다른 서버 또는 위치(http, fastcgi, scgi 및 uwsgi 프록시 사용).

기타 컨텍스트

위의 예는 Nginx에서 접하게 될 필수 컨텍스트를 나타내지만 다른 컨텍스트도 존재합니다. 다음 컨텍스트는 특정 상황에서만 사용되거나 대부분의 사람들이 사용하지 않는 기능에 사용됩니다.

  • split_clients: 이 컨텍스트는 서버가 받는 클라이언트를 백분율을 기준으로 변수로 레이블을 지정하여 범주로 분할하도록 구성됩니다. 그런 다음 다른 호스트에 다른 콘텐츠를 제공하여 A/B 테스트를 수행하는 데 사용할 수 있습니다.
  • perl/perl_set: 이 컨텍스트는 Perl 처리기가 표시되는 위치에 대해 구성합니다. Perl 처리에만 사용됩니다.
  • map: 이 컨텍스트는 다른 변수의 값에 따라 변수의 값을 설정하는 데 사용됩니다. 두 번째 변수를 무엇으로 설정해야 하는지 결정하기 위해 한 변수 값의 매핑을 제공합니다.
  • geo: 위 컨텍스트와 마찬가지로 이 컨텍스트는 매핑을 지정하는 데 사용됩니다. 그러나 이 매핑은 특히 클라이언트 IP 주소를 분류하는 데 사용됩니다. 연결 IP 주소에 따라 변수의 값을 설정합니다.
  • types: 이 컨텍스트는 다시 매핑에 사용됩니다. 이 컨텍스트는 MIME 유형을 연결해야 하는 파일 확장명에 매핑하는 데 사용됩니다. 이는 일반적으로 기본 nginx.conf 구성 파일에 있는 파일을 통해 Nginx와 함께 제공됩니다.
  • charset_map: 매핑 컨텍스트의 또 다른 예입니다. 이 컨텍스트는 한 문자 집합에서 다른 문자 집합으로 변환 테이블을 매핑하는 데 사용됩니다. 컨텍스트 헤더에는 두 세트가 모두 나열되고 본문에는 매핑이 발생합니다.

업스트림 컨텍스트

업스트림 컨텍스트는 "업스트림” 서버를 정의하고 구성하는 데 사용됩니다. 이 컨텍스트는 Nginx가 요청을 프록시할 수 있는 명명된 서버 풀을 정의합니다. 이 컨텍스트는 다양한 유형의 프록시를 구성할 때 사용됩니다.

업스트림 컨텍스트는 특정 서버 컨텍스트 외부의 http 컨텍스트 내에 배치되어야 합니다. 양식은 다음과 같습니다.

# main context

http {

    # http context

    upstream upstream_name {

        # upstream context

        server proxy_server1;
        server proxy_server2;

        . . .

    }

    server {

        # server context

    }

}

업스트림 컨텍스트는 정의된 서버 풀에 특정 유형의 요청을 전달하기 위해 서버 또는 위치 블록 내의 이름으로 참조될 수 있습니다. 그런 다음 업스트림은 알고리즘(기본적으로 라운드 로빈)을 사용하여 요청을 전달할 특정 서버를 결정합니다. 이 컨텍스트는 Nginx가 요청을 프록싱할 때 로드 밸런싱을 수행할 수 있는 기능을 제공합니다.

If 컨텍스트

"if\ 컨텍스트는 지시문의 조건부 처리를 제공하도록 설정할 수 있습니다. 기존 프로그래밍의 if 문과 마찬가지로 Nginx의 if 지시문은 주어진 테스트에서 "true\를 반환하는 경우 포함된 명령을 실행합니다.

Nginx의 if 컨텍스트는 rewrite 모듈에 의해 제공되며 이것이 이 컨텍스트의 주요 용도입니다. Nginx는 목적에 맞게 만들어진 다른 많은 지시문을 사용하여 요청 조건을 테스트하므로 대부분의 조건부 실행 형식에 if를 사용하면 안 됩니다. 이것은 Nginx 커뮤니티가 if is evil이라는 페이지를 만든 중요한 메모입니다.

문제는 Nginx 처리 순서가 매우 자주 예기치 않은 결과를 초래할 수 있다는 것입니다. 이러한 컨텍스트 내에서 사용하기에 안정적으로 안전한 것으로 간주되는 유일한 지시어는 returnrewrite 지시어(이 컨텍스트가 생성된 지시어)입니다. if 컨텍스트를 사용할 때 염두에 두어야 할 또 다른 사항은 동일한 컨텍스트에서 try_files 지시문을 쓸모 없게 만든다는 것입니다.

대부분의 경우 if는 재작성 또는 반환이 필요한지 여부를 결정하는 데 사용됩니다. 위치 블록에 가장 자주 존재하므로 일반적인 형식은 다음과 같습니다.

# main context

http {

    # http context

    server {

        # server context

        location location_match {

            # location context

            if (test_condition) {

                # if context

            }

        }

    }

}

Limit_except 컨텍스트

limit_except 컨텍스트는 위치 컨텍스트 내에서 특정 HTTP 메서드의 사용을 제한하는 데 사용됩니다. 예를 들어 특정 클라이언트만 POST 콘텐츠에 액세스할 수 있어야 하지만 모든 사람이 콘텐츠를 읽을 수 있어야 하는 경우 limit_except 블록을 사용하여 이 요구 사항을 정의할 수 있습니다.

위의 예는 다음과 같습니다.

. . .

# server or location context

location /restricted-write {

    # location context

    limit_except GET HEAD {

        # limit_except context

        allow 192.168.1.1/24;
        deny all;
    }
}

이는 컨텍스트 헤더에 나열된 것을 제외한 모든 HTTP 메서드를 만날 때 컨텍스트 내부의 지시문(액세스 제한을 의미함)을 적용합니다. 위 예제의 결과는 모든 클라이언트가 GET 및 HEAD 동사를 사용할 수 있지만 192.168.1.1/24 서브넷에서 오는 클라이언트만 다른 메서드를 사용할 수 있다는 것입니다.

컨텍스트와 관련하여 따라야 할 일반 규칙

이제 Nginx 구성을 탐색할 때 접할 수 있는 일반적인 컨텍스트에 대한 아이디어를 얻었으므로 Nginx 컨텍스트를 처리할 때 사용할 몇 가지 모범 사례에 대해 논의할 수 있습니다.

사용 가능한 최상위 컨텍스트에서 지시문 적용

많은 지시문이 둘 이상의 컨텍스트에서 유효합니다. 예를 들어 http, 서버 또는 위치 컨텍스트에 배치할 수 있는 꽤 많은 지시문이 있습니다. 이렇게 하면 이러한 지시문을 유연하게 설정할 수 있습니다.

일반적으로 적용 가능한 최상위 컨텍스트에서 지시문을 선언하고 필요에 따라 하위 컨텍스트에서 재정의하는 것이 일반적으로 가장 좋습니다. 이는 Nginx가 구현하는 상속 모델 때문에 가능합니다. 이 전략을 사용하는 데는 여러 가지 이유가 있습니다.

우선 상위 수준에서 선언하면 형제 컨텍스트 간에 불필요한 반복을 피할 수 있습니다. 예를 들어 아래 예에서 각 위치는 동일한 문서 루트를 선언합니다.

http {
    server {
        location / {
            root /var/www/html;

            . . .

        }

        location /another {
            root /var/www/html;

            . . .

        }

    }
}

다음과 같이 루트를 서버 블록 또는 http 블록으로 이동할 수 있습니다.

http {
    root /var/www/html;
    server {
        location / {

            . . .

        }

        location /another {

            . . .

        }
    }
}

대부분의 경우 서버 수준이 가장 적합하지만 상위 수준에서 선언하는 것이 장점이 있습니다. 이렇게 하면 지시어를 더 적은 위치에 설정할 수 있을 뿐만 아니라 기본값을 모든 하위 요소로 캐스케이드할 수 있으므로 하위 수준에서 지시어를 잊어버려 오류가 발생하는 상황을 방지할 수 있습니다. 이것은 긴 구성에서 중요한 문제가 될 수 있습니다. 더 높은 수준에서 선언하면 좋은 기본값이 제공됩니다.

처리를 위해 If 로직 대신 여러 형제 컨텍스트 사용

클라이언트의 요청에서 찾을 수 있는 일부 정보에 따라 요청을 다르게 처리하려는 경우 사용자는 종종 "if\ 컨텍스트로 이동하여 조건부 처리를 시도합니다. 앞에서 간략하게 언급한 몇 가지 문제가 있습니다.

첫 번째는 "if\ 지시문이 관리자의 기대와 일치하지 않는 결과를 반환하는 경우가 많다는 것입니다. 동일한 입력이 주어지면 처리가 항상 동일한 결과로 이어지지만 Nginx가 환경을 해석하는 방식은 실제와 다를 수 있습니다. 무거운 테스트없이 가정.

이에 대한 두 번째 이유는 이러한 많은 목적에 사용되는 최적화된 특수 목적 지시문이 이미 있기 때문입니다. Nginx는 이미 서버 블록 및 위치 블록 선택과 같은 항목에 잘 문서화된 선택 알고리즘을 사용합니다. 가능한 경우 이 알고리즘이 선택 프로세스 논리를 처리할 수 있도록 서로 다른 구성을 자체 블록으로 이동하는 것이 가장 좋습니다.

예를 들어 사용자가 제공한 요청을 작업하려는 형식으로 가져오기 위해 재작성에 의존하는 대신 요청에 대해 두 개의 블록을 설정해야 합니다. 그 중 하나는 원하는 메서드를 나타내고 다른 하나는 지저분한 요청 및 올바른 블록으로 리디렉션(및 재작성)합니다.

결과는 일반적으로 더 읽기 쉽고 성능이 더 좋다는 추가 이점도 있습니다. 올바른 요청은 추가 처리를 거치지 않으며, 대부분의 경우 잘못된 요청은 재작성이 아닌 리디렉션을 통해 얻을 수 있으며, 이는 낮은 오버헤드로 실행되어야 합니다.

결론

이 시점에서 Nginx의 가장 일반적인 컨텍스트와 이를 정의하는 블록을 생성하는 지시문을 잘 이해하고 있어야 합니다.

디렉티브를 배치할 수 있는 컨텍스트에 대한 정보와 가장 효과적인 위치를 평가하려면 Nginx의 문서를 항상 확인하십시오. 구성을 만들 때 주의를 기울이면 유지 관리가 향상되고 종종 성능도 향상됩니다.

다음으로 Nginx로 비밀번호 인증을 구성하는 방법을 배울 수 있습니다.