Nginx 설정 명령 의 실행 순서 (1)

13241 단어 nginx
대부분의 Nginx 초보 자 들 은 이러한 곤 혹 스 러 움 을 자주 만난다. 그것 은 바로 같은 사람 이 되 는 것 이다.  location  설정 블록 이 여러 Nginx 모듈 의 설정 명령 을 사 용 했 을 때 이 명령 들 의 실행 순 서 는 쓰기 순서 와 크게 다 를 수 있 습 니 다.그래서 많은 사람들 이 '시행 착오 법' 을 선택 한 후에 그들의 프로필 은 항상 엉망 으로 바 뀌 었 다.이 시리즈 의 튜 토리 얼 은 독자 들 이 이러한 배치 명령 뒤의 집행 시간 과 선착순 의 비밀 을 점차적으로 이해 하도록 돕 는 데 목적 을 둔다.
 
    지금 바로 이런 곤 혹 스 러 운 예 를 살 펴 보 자.
    ? location /test {
    ?     set $a 32;
    ?     echo $a;
    ?
    ?     set $a 56;
    ?     echo $a;
    ? }

이 예 의 본 뜻 을 보면 우리 가 기대 하 는 수출 은 한 줄 이다.  32  일행  56 저희 가 처음 써 봐 서 요.  echo  설정 명령 출력  $a 변수의 값 을 이어서 사용 합 니 다.  set  설정 명령 이 수정 되 었 습 니 다.  $a. 그러나 불행 하 게 도 사실은 그렇지 않다.
    $ curl 'http://localhost:8080/test
    56
    56

보다  set $a 56  첫 번 째 줄 에 있 는 것 같 아 요.  echo $a  문 구 는 이미 집행 되 었 다.이게 도대체 왜 일 까요?설마 우리 가 Nginx 중의 bug 를 만 났 단 말 인가?
 
    분명히 여 기 는 Nginx 의 bug 가 없습니다.여기 서 일어 난 일 을 이해 하려 면 먼저 Nginx 가 모든 사용자 의 요청 을 처리 할 때 여러 단계 (phase) 에 따라 순서대로 처리 한 다 는 것 을 알 아야 한다.
 
    Nginx 의 요청 처리 단 계 는 모두 11 개 이상 이 므 로 그 중 3 개 를 먼저 소개 합 니 다.그것들 이 실 행 될 때의 선후 순서에 따라 순서대로  rewrite  단계, access 단계 및  content  단계.
 
    모든 Nginx 모듈 에서 제공 하 는 설정 명령 은 보통 하나의 처리 단계 에 만 등록 되 고 실 행 됩 니 다.예 를 들 면 상례 중의  set  지령 은  rewrite  단계 적  echo  지령 은  content  단계 운행.앞에서 우 리 는 단일 요청 의 처리 과정 에서 rewrite 단계  content  단계 전에 실행 하기 때문에  rewrite  단계 설정 명령 도 무조건 content 단계 설정 명령 을 실행 하기 전에 실행 합 니 다.그래서 같은  location  설정 블록 중, set 명령 은 항상  echo  명령 을 실행 하기 전에 설정 파일 에서 의도 적 으로 실행 하 더 라 도  set  문장  echo  문장의 뒤.
 
    아까 그 예 로 돌아 가면,
    set $a 32;
    echo $a;
 
    set $a 56;
    echo $a;

실제 집행 순 서 는
    set $a 32;
    set $a 56;
    echo $a;
    echo $a;

먼저  rewrite  단 계 는 여기 두 가 지 를 완 료 했 습 니 다.  set  할당 문  content  단 계 는 그 두 가 지 를 순서대로 집행 한다.  echo 문구.두 개의 서로 다른 처리 단계 에 속 하 는 설정 명령 사 이 를 삽입 하여 실행 할 수 없습니다.
 
    이 점 을 더욱 검증 하기 위해 서 는 Nginx 의 '디 버 깅 로그' 를 통 해 Nginx 의 실제 실행 과정 을 살 펴 보 자.
 
    이것 은 우리 가 처음으로 Nginx 의 '디 버 깅 로그' 를 언급 한 것 이기 때문에 먼저 그것 의 사용 방법 을 간단하게 소개 할 필요 가 있다.디 버 깅 로 그 는 기본적으로 사용 하지 않 습 니 다. 큰 실행 시 비용 이 들 기 때문에 Nginx 서버 가 현저히 느 려 집 니 다.일반적으로 우 리 는 Nginx 실행 가능 한 파일 을 다시 컴 파일 하고 구성 해 야 하 며, Nginx 원본 패키지 에서 제공 하 는  ./configure  스 크 립 트 전송  --with-debug  명령 행 옵션.예 를 들 어 우리 가 Nginx 소스 패 키 지 를 다운로드 한 후에 리 눅 스 나 Mac OS X 등 시스템 에서 구축 할 때 전형 적 인 절 차 는 다음 과 같다.
    tar xvf nginx-1.0.10.tar.gz
    cd nginx-1.0.10/
    ./configure --with-debug
    make
    sudu make install

하면, 만약, 만약...  ngx_openresty  패키지  ./configure  스 크 립 트 전달  --with-debug  명령 행 옵션.
 
    우리 가 사용 할 때  --with-debug  디 버 깅 버 전의 Nginx 를 다시 만 들 려 면 설정 파일 에서 표준 error_log 을 통과 해 야 합 니 다. 오류 로그 사용 명령 설정  debug  로그 단계 (이것 은 가장 낮은 로그 단계 이기 도 합 니 다):
    error_log logs/error.log debug;

여기 서 중요 한 건  error_log  명령 의 두 번 째 매개 변 수 는 debug 이 고 앞의 첫 번 째 매개 변 수 는 오류 로그 파일 의 경로 입 니 다. logs/error.log 물론 다른 경 로 를 지정 할 수 있 지만 나중에 이 파일 의 내용 을 검사 할 것 입 니 다. 따라서 실제 설 정 된 파일 경 로 를 주의 하 십시오.
 
    현재 우 리 는 Nginx 를 다시 시작 합 니 다. (Nginx 가 실행 가능 한 파일 도 업데이트 되 었 다 면 Nginx 가 설정 을 다시 불 러 오 는 것 만 으로 는 부족 합 니 다. Nginx 메 인 서비스 프로 세 스 를 닫 고 다시 시작 해 야 합 니 다.) 그리고 방금 예제 인 터 페 이 스 를 요청 하 십시오.
    $ curl 'http://localhost:8080/test'
    56
    56

현재 설정 한 Nginx 오류 로그 파일 의 출력 을 확인 할 수 있 습 니 다.파일 에 출력 이 많 기 때문에 (내 기계 에 700 여 줄 이 있다) 사용 해도 무방 하 다.  grep  명령 은 터미널 에서 우리 가 관심 있 는 부분 을 걸 러 냅 니 다:
    grep -E 'http (output filter|script (set|value))' logs/error.log

제 기계 에서 의 출력 은 이 모양 입 니 다.  grep  명령 의 실제 출력 은 간단 한 편집 을 하여 줄 마다 첫 번 째 시간 스탬프 를 생략 합 니 다):
    [debug] 5363#0: *1 http script value: "32"
    [debug] 5363#0: *1 http script set $a
    [debug] 5363#0: *1 http script value: "56"
    [debug] 5363#0: *1 http script set $a
    [debug] 5363#0: *1 http output filter "/test?"
    [debug] 5363#0: *1 http output filter "/test?"
    [debug] 5363#0: *1 http output filter "/test?"

이 디 버 깅 정보의 구체 적 인 의 미 를 조금 설명해 야 한다.set  설정 명령 은 실제 실행 중 두 줄 로 인쇄 됩 니 다.  http script  시작 디 버 깅 정보 중 첫 번 째 줄 정 보 는?  set  문장 에 부 여 된 값, 두 번 째 줄 은  set  구문 에 부 여 된 Nginx 변수 이름 입 니 다.그래서 위 에서 먼저 걸 러 낸 거 예요.
    [debug] 5363#0: *1 http script value: "32"
    [debug] 5363#0: *1 http script set $a

이 두 줄 은 우리 예 에서 의 설정 문 에 대응 합 니 다.
    set $a 32;

다음 두 줄 의 디 버 깅 정보
    [debug] 5363#0: *1 http script value: "56"
    [debug] 5363#0: *1 http script set $a

대응 설정 문
    set $a 56;

또한, Nginx 에서 응답 체 데 이 터 를 출력 할 때 Nginx 의 이른바 '출력 필터' (output filter) 를 호출 합 니 다. 저 희 는 항상 사용 하고 있 습 니 다.  echo  지령 도 예 외 는 아니다.Nginx 의 '출력 필터' 를 호출 하면 다음 과 같은 디 버 깅 정보 가 발생 합 니 다.
    [debug] 5363#0: *1 http output filter "/test?"

물론  "/test?"  일부 다른 인터페이스 에 변화 가 생 길 수 있 습 니 다. 현재 요청 한 URI 를 표시 하기 때 문 입 니 다. 이렇게 연결 해 보면 상기 두 개 를 발견 하기 어렵 지 않 습 니 다.  set  문 구 는 확실히 그 두 개 에 있다.  echo  문장 전에 실 행 된 것 이다.
 
    세심 한 독자 들 은 왜 이 예 는 분명히 두 가지 만 사 용 했 느 냐 고 물 을 수 있다.  echo  문장 을 출력 하지만 세 줄 이 있다  http output filter  디 버 깅 정 보 는?사실 앞의 두 줄 은  http output filter  정 보 는 확실히 그 두 가지 에 대응 된다.  echo  문장, 마지막 줄 의 정 보 는 대응  ngx_echo  모듈 출력 지시 응답 체 끝의 끝 표시.이 특수 한 끝 표 시 를 출력 하기 위해 서 Nginx '출력 필터' 를 한 번 더 호출 할 수 있 습 니 다.포괄 하 다  ngx_proxy  이 를 포함 한 많은 모듈 은 응답 체 데이터 흐름 을 출력 할 때 이러한 행 위 를 한다.
 
    지금 우 리 는 다 시 는 앞의 그 예 를 위해 두 줄 을 똑 같이 출력 하지 않 을 것 이다.  56  놀 랐 습 니 다.우 리 는 두 번 째 조 에 있 을 기회 가 전혀 없다.  set 문 구 를 사용 하기 전에  echo  수출다행히도 작은 기 교 를 빌려 최초의 목적 을 달성 할 수 있다.
    location /test {
        set $a 32;
        set $saved_a $a;
        set $a 56;
 
        echo $saved_a;
        echo $a;
    }

이때 의 출력 은 그 문제 예제 의 취지 에 부합된다.
    $ curl 'http://localhost:8080/test'
    32
    56

새로운 사용자 변 수 를 도입 합 니 다.  $saved_a, 고 쳐 쓰 고 있 습 니 다.  $a  그 전에 바로 저 장 했 습 니 다.  $a  의 초기 값.여러 가지  set  명령 의 경우, 그들 사이 의 집행 순 서 는?  ngx_rewrite  모듈 은 쓰기 순서 와 일치 하도록 보장 합 니 다.같은 이치 로, ngx_echo 모듈 자체 도 여러 가 지 를 보장 합 니 다.  echo  명령 간 의 실행 순서.
 
    세심 한 독 자 는 우리 가  Nginx 변수 로 밍 시리즈  의 예제 에 서 는 이미 이러한 기 교 를 광범 위 하 게 사용 하여 처리 단계 로 인 한 명령 집행 순서 상의 제한 을 우회 하 였 다.
 
    이 를 보고 어떤 독자 들 은 "그렇다면 낯 선 설정 명령 을 사용 하기 전에 어떤 처리 단계 에서 실행 되 는 지 어떻게 알 수 있 습 니까?" 라 고 물 을 수 있 습 니 다. 정 답 은 이 명령 의 문 서 를 보 는 것 입 니 다 (물론 고급 개발 자 들 도 모듈 의 C 소스 코드 를 직접 볼 수 있 습 니 다).많은 모듈 문서 에 서 는 설정 명령 이 실행 되 는 구체 적 인 단 계 를 표시 합 니 다.예컨대  echo  명령 어 문서 에 다음 줄 이 있 습 니 다:
    phase: content

이 줄 은 현재 설정 명령 이 실 행 됩 니 다.  content  단계만약 당신 이 사용 하 는 Nginx 모듈 이 공교롭게도 실행 단 계 를 가리 키 는 문서 가 없다 면, 이 모듈 의 작성 자 에 게 직접 연락 하여 보충 을 요청 할 수 있 습 니 다.그러나 주의해 야 할 것 은 모든 설정 명령 이 특정한 처리 단계 와 관련 된 것 이 아니다. 예 를 들 어 우리 가 이전에  Nginx 변수 로 밍 (1)  언급  geo  지령  Nginx 변수 로 밍 (4)  소개  map  지령처리 단계 와 관련 이 없 는 설정 명령 은 기본적으로 '성명 적' (declarative) 으로 특정한 동작 이나 과정 이 직접적 으로 발생 하지 않 습 니 다.Nginx 의 작성 자 Igor Sysoev 는 공식 석상 에서 Nginx 프로필 이 사용 하 는 언어 는 본질 적 으로 '프로 세 스 적' (procedural) 이 아니 라 '성명 적' 이 라 고 강조 한 적 이 한두 번 이 아니다.

좋은 웹페이지 즐겨찾기