블로그 | NGINX

NGINX 및 NGINX Plus용 OpenTracing

NGINX-F5-수평-검정-유형-RGB의 일부
모하메드 고우감 썸네일
모하메드 고감
2019년 6월 17일 게시

이러한 이점에도 불구하고 마이크로서비스 아키텍처는 새로운 복잡성도 초래합니다. 그 중 하나는 애플리케이션을 구성하는 모든 마이크로서비스 간에 데이터가 흐르면서 처리되는 요청을 추적하는 과제입니다. 이러한 목적을 위해 분산(요청) 추적 이라는 새로운 방법론이 발명되었으며, OpenTracing은 분산 추적 도구의 설계와 구현을 안내하기 위한 사양 및 표준 API 집합입니다.

NGINX Plus 릴리스 18(R18) 에서 NGINX OpenTracing 모듈을 동적 모듈 저장소에 추가했습니다(이 모듈은 몇 년 동안 GitHub에서 타사 모듈 로 제공되었습니다). NGINX OpenTracing 모듈의 가장 큰 장점은 분산 추적을 위해 NGINX 및 NGINX Plus를 계측하면 개별적으로 애플리케이션을 계측하지 않고도 모든 프록시 애플리케이션에 대한 추적 데이터를 얻을 수 있다는 것입니다.

이 블로그에서는 NGINX 또는 NGINX Plus에 대한 요청의 분산 추적을 활성화하는 방법을 보여드립니다(간단히 말해서 지금부터는 NGINX Plus 라고만 지칭합니다). OpenTracing 용어로 '추적기 '라고 불리는 두 가지 분산 추적 서비스인 JaegerZipkin에 대한 지침을 제공합니다. (다른 추적기 목록은 OpenTracing 설명서를 참조하세요.) 추적자가 제공하는 정보의 종류를 설명하기 위해 NGINX Plus 캐싱이 활성화되기 전과 후의 요청 처리를 비교해보겠습니다.

추적기에는 두 가지 기본 구성 요소가 있습니다.

  • 호스트에서 실행되는 애플리케이션에서 추적 데이터를 수집하는 에이전트입니다. 우리의 경우, "애플리케이션"은 NGINX Plus이고 에이전트는 플러그인으로 구현됩니다.
  • 하나 이상의 에이전트로부터 추적 데이터를 수신하고 중앙 UI에 표시하는 서버( 수집기 라고도 함). 원하는 대로 NGINX Plus 호스트나 다른 호스트에서 서버를 실행할 수 있습니다.

추적 서버 설치

첫 번째 단계는 선택한 추적기에 대한 서버를 설치하고 구성하는 것입니다. Jaeger와 Zipkin에 대한 지침을 제공하고 있습니다. 필요에 따라 다른 추적자에게도 적용하세요.

Jaeger 서버 설치

Jaeger 서버를 설치하려면 다음 방법을 권장합니다. 1단계에서 지정한 URL에서 Docker 이미지를 다운로드할 수도 있습니다.

  1. Jaeger 다운로드 페이지 로 이동하여 Linux 바이너리를 다운로드하세요(이 글을 쓰는 시점에서는 jaeger-1.12.0-linux-amd64.tar ).

  2. 바이너리를 /usr/bin/jaeger 로 옮기고(필요하다면 먼저 디렉토리를 생성하고) 실행합니다.

    $ mkdir /usr/bin/jaeger $ mv jaeger-1.12.0-linux-amd64.tar /usr/bin/jaeger $ cd /usr/bin/jaeger $ tar xvzf jaeger-1.12.0-linux-amd64.tar.gz $ sudo rm -rf jaeger-1.12.0-linux-amd64.tar.gz $ cd jaeger-1.12.0-linux-amd64 $ ./jaeger-올인원
  3. 브라우저에서 http:// Jaeger-server-IP-address :16686/ 에서 Jaeger UI에 액세스할 수 있는지 확인하세요(16686은 Jaeger 서버의 기본 포트입니다).

Zipkin 서버 설치

  1. Zipkin의 Docker 이미지를 다운로드하여 실행합니다(기본값인 포트 9411을 사용합니다).

    $ docker run -d -p 9411:9411 오픈지킨/지킨
  2. 브라우저에서 http:// Zipkin-server-IP-address :9411/ 에서 Zipkin UI에 액세스할 수 있는지 확인하세요.

Tracer 플러그인 설치 및 구성

Jaeger 또는 Zipkin 플러그인을 설치하려면 NGINX Plus 호스트에서 다음 명령을 실행하세요.

Jaeger 플러그인 설치

  1. Jaeger 플러그인을 설치하세요. 다음 wget 명령은 x86‑64 Linux 시스템용입니다.

    $ cd /usr/local/lib $ wget https://github.com/jaegertracing/jaeger-client-cpp/releases/download/v0.4.2/libjaegertracing_plugin.linux_amd64.so -O /usr/local/lib/libjaegertracing_plugin.so

    소스에서 플러그인을 빌드하는 방법에 대한 지침은 GitHub 에서 제공됩니다.

  2. 다음 내용을 포함하여 /etc/jaeger/jaeger-config.json 이라는 이름의 플러그인에 대한 JSON 형식의 구성 파일을 만듭니다. Jaeger 서버의 기본 포트인 6831을 사용하고 있습니다.

    { "서비스 이름": "nginx", "샘플러": { "유형": "상수", "매개변수": 1 }, "reporter": { "localAgentHostPort": " Jaeger 서버 IP 주소 : 6831 " } }

    샘플러 객체에 대한 자세한 내용은 Jaeger 설명서를 참조하세요.

Zipkin 플러그인 설치

  1. Zipkin 플러그인을 설치하세요. 다음 wget 명령은 x86‑64 Linux 시스템용입니다.

    $ cd /usr/local/lib $ wget -O - https://github.com/rnburn/zipkin-cpp-opentracing/releases/download/v0.5.2/linux-amd64-libzipkin_opentracing_plugin.so.gz | gunzip -c > /usr/local/lib/libzipkin_opentracing_plugin.so
  2. 다음 내용을 포함하여 /etc/zipkin/zipkin-config.json 이라는 이름의 플러그인에 대한 JSON 형식의 구성 파일을 만듭니다. Zipkin 서버의 기본 포트인 9411을 사용하고 있습니다.

    { "서비스 이름": "nginx", "수집기 호스트": " Zipkin-server-IP-address ", "collector_port": 9411 }

    구성 개체에 대한 자세한 내용은 GitHub의 JSON 스키마를 참조하세요.

NGINX Plus 구성

NGINX Plus 호스트에서 이 지침을 수행하세요.

  1. NGINX Plus 관리자 가이드 의 지침에 따라 NGINX OpenTracing 모듈을 설치하세요.

  2. 다음 load_module 지시문을 NGINX Plus 구성 파일( /etc/nginx/nginx.conf )의 기본(최상위) 컨텍스트에 추가합니다.

    로드_모듈 모듈/ngx_http_opentracing_module.so;
  3. NGINX Plus 구성에 다음 지침을 추가합니다.

    기존 구성 방식을 사용하는 경우 /etc/nginx/conf.d/opentracing.conf 라는 새 파일에 지침을 넣습니다. 또한 다음 include 지시문이 /etc/nginx/nginx.confhttp 컨텍스트에 나타나는지 확인하세요.

    http {
    /etc/nginx/conf.d/*.conf를 포함합니다.
    }
    • opentracing_load_tracer 지시어는 추적 플러그인을 활성화합니다. Jaeger 또는 Zipkin에 대한 지시문의 주석 처리를 적절히 해제하세요.
    • opentracing_tag 지시어는 NGINX Plus 변수를 추적기 UI에 나타나는 OpenTracing 태그로 사용할 수 있도록 합니다.
    • OpenTracing 활동을 디버깅하려면 log_formataccess_log 지시문의 주석 처리를 제거합니다. 기본 NGINX 액세스 로그와 로그 형식을 이것으로 바꾸려면 지시문의 주석 처리를 해제한 후 " opentracing "의 세 인스턴스를 " main "으로 변경합니다. 또 다른 옵션은 포트 9001의 트래픽에 대해서만 OpenTracing 활동을 기록하는 것입니다. log_formataccess_log 지시문의 주석 처리를 제거하고 이를 server 블록으로 이동합니다.
    • 서버 블록은 다음 섹션 에 설명된 샘플 Ruby 애플리케이션에 대한 OpenTracing을 설정합니다.
    # 공급업체 추적기 로드#opentracing_load_tracer /usr/local/libjaegertracing_plugin.so 
    # /etc/jaeger/jaeger-config.json;
    #opentracing_load_tracer /usr/local/lib/libzipkin_opentracing_plugin.so
    # /etc/zipkin/zipkin-config.json;
    
    # 모든 요청에 대한 추적 활성화
    opentracing on;
    
    # NGINX Plus 변수의 값을 캡처하는 추가 태그 설정
    opentracing_tag bytes_sent $bytes_sent;
    opentracing_tag http_user_agent $http_user_agent;
    opentracing_tag request_time $request_time;
    opentracing_tag upstream_addr $upstream_addr;
    opentracing_tag upstream_bytes_received $upstream_bytes_received;
    opentracing_tag 업스트림_캐시_상태 $업스트림_캐시_상태;
    opentracing_tag 업스트림_연결_시간 $업스트림_연결_시간;
    opentracing_tag 업스트림_헤더_시간 $업스트림_헤더_시간;
    opentracing_tag 업스트림_큐_시간 $업스트림_큐_시간;
    opentracing_tag 업스트림_응답_시간 $업스트림_응답_시간;
    
    # 디버깅을 위한 주석 해제
    # log_format opentracing '$remote_addr - $remote_user [$time_local] "$request" '
    # '$status $body_bytes_sent "$http_referer" '
    # '"$http_user_agent" "$http_x_forwarded_for" '
    # '"$host" sn="$server_name" '
    # 'rt=$request_time '
    # 'ua="$upstream_addr" us="$upstream_status" '
    # 'ut="$upstream_response_time" ul="$upstream_response_length" '
    # 'cs=$upstream_cache_status';
    #access_log /var/log/nginx/opentracing.log opentracing;
    
    server {
    listen 9001;
    
    location / {
    # OpenTracing Span에 사용되는 작업 이름은 기본적으로
    # 'location' 블록의 이름으로 지정되지만, 이 지시문의 주석 처리를 제거하여 사용자 정의합니다.
    #opentracing_operation_name $uri;
    
    # 활성 Span 컨텍스트를 업스트림으로 전파하여 백엔드에서 추적을 계속할 수 있도록 합니다.
    opentracing_propagate_context;
    
    # Ruby 앱이 포트 4567에서 수신 대기하고 있는지 확인합니다.
    proxy_pass http://127.0.0.1:4567;
    }
    }
  4. NGINX Plus 구성을 검증하고 다시 로드합니다.

    $ nginx -t $ nginx -s 다시로드

샘플 루비 앱 설정

추적기와 NGINX Plus 구성이 완료되면 OpenTracing 데이터가 어떤 모습인지 보여주는 샘플 Ruby 앱을 만듭니다. 이 앱을 사용하면 NGINX Plus 캐싱이 응답 시간을 얼마나 개선하는지 측정할 수 있습니다. 앱이 다음과 같은 / 에 대한 HTTP GET 요청과 같은 요청을 받으면 응답하기 전에 임의의 시간(2~5초) 동안 기다립니다.

$ curl http:// NGINX-Plus-IP-주소 :9001/
  1. RubySinatra (Ruby로 작성된 오픈 소스 소프트웨어 웹 애플리케이션 라이브러리이자 도메인 특정 언어로, 다른 Ruby 웹 애플리케이션 프레임워크에 대한 대안으로 사용됨)를 모두 설치하고 설정합니다.

  2. 다음 내용으로 app.rb 라는 파일을 만듭니다.

    #!/usr/bin/ruby
    
    require 'sinatra'
    
    get '/*' do
    out = "<h1>Ruby simple app</h1>" + "\n"
    
    # 2초에서 5초 사이의 임의의 시간 동안 sleep
    sleeping_time = rand(4)+2
    sleep(sleeping_time)
    puts "slept for: #{sleeping_time}s."
    out += '<p>some output text</p>' + "\n"
    
    return out
    end
  3. app.rb를 실행 가능하게 만들고 실행합니다.

    $ chmod +x 앱.rb $ ./앱.rb

캐싱 없이 응답 시간 추적

캐싱이 활성화되지 않은 경우 NGINX Plus가 요청에 응답하는 데 걸리는 시간을 보여주기 위해 Jaeger와 Zipkin을 사용합니다. 각 추적자에 대해 5개의 요청을 보냅니다.

캐싱 없이 Jaeger에서 출력

Jaeger UI에 표시되는 5가지 요청은 다음과 같습니다(최신 요청이 먼저 표시됨):

Ruby 앱 콘솔에 대한 동일한 정보는 다음과 같습니다.

- -> /잠을 잤습니다: 3초. 
127.0.0.1 - - [2019년 6월 7일: 10:50:46 +0000] "GET / HTTP/1.1" 200 49 3.0028
127.0.0.1 - - [2019년 6월 7일: 10:50:43 UTC] "GET / HTTP/1.0" 200 49
- -> /
잠자기: 2초. 
127.0.0.1 - - [2019년 6월 7일: 10:50:56 +0000] "GET / HTTP/1.1" 200 49 2.0018 
127.0.0.1 - - [2019년 6월 7일: 10:50:54 UTC] "GET / HTTP/1.0"1 200 49
- -> /
잠자기 시간: 3초. 
127.0.0.1 - - [2019년 6월 7일: 10:53:16 +0000] "GET / HTTP/1.1" 200 49 3.0029 
127.0.0.1 - - [2019년 6월 7일: 10:53:13 UTC] "GET / HTTP/1.0" 200 49
- -> /
잠자기: 4초.
127.0.0.1 - - [2019년 6월 7일: 10:54:03 +0000] "GET / HTTP/1.1" 200 49 4.0030 
127.0.0.1 - - [2019년 6월 7일: 10:53:59 UTC] "GET / HTTP/1.0" 200 49
- -> /
잠자기: 3초.
127.0.0.1 - - [2019년 6월 7일: 10:54:11 +0000] "GET / HTTP/1.1" 200 49 3.0012
127.0.0.1 - - [2019년 6월 7일: 10:54:08 UTC] "GET / HTTP/1.0" 200 49

Jaeger UI에서 첫 번째(가장 최근) 요청을 클릭하면 태그로 추가한 NGINX Plus 변수의 값을 포함한 해당 요청에 대한 세부 정보를 볼 수 있습니다.

캐싱 없이 Zipkin에서 출력

Zipkin UI의 다른 5가지 요청은 다음과 같습니다.

Ruby 앱 콘솔에 대한 동일한 정보:

- -> /잠을 잤습니다: 2초.
127.0.0.1 - - [2019년 6월 7일: 10:31:18 +0000] "GET / HTTP/1.1" 200 49 2.0021 
127.0.0.1 - - [2019년 6월 7일: 10:31:16 UTC] "GET / HTTP/1.0" 200 49
- -> /
잠자기: 3초.
127.0.0.1 - - [2019년 6월 7일: 10:31:50 +0000] "GET / HTTP/1.1" 200 49 3.0029 
127.0.0.1 - - [2019년 6월 7일: 10:31:47 UTC] "GET / HTTP/1.0" 200 49
- -> /
잠자기: 3초.
127.0.0.1 - - [2019년 6월 7일: 10:32:08 +0000] "GET / HTTP/1.1" 200 49 3.0026 
127.0.0.1 - - [2019년 6월 7일: 10:32:05 UTC] "GET / HTTP/1.0" 200 49
- -> /
잠자기: 3초.
127.0.0.1 - - [2019년 6월 7일: 10:32:32 +0000] "GET / HTTP/1.1" 200 49 3.0015 
127.0.0.1 - - [2019년 6월 7일: 10:32:29 UTC] "GET / HTTP/1.0" 200 49
- -> /
잠자기: 5초.
127.0.0.1 - - [2019년 6월 7일: 10:32:52 +0000] "GET / HTTP/1.1" 200 49 5.0030 
127.0.0.1 - - [2019년 6월 7일: 10:32:47 UTC] "GET / HTTP/1.0" 200 49

Zipkin UI에서 첫 번째 요청을 클릭하면 태그로 추가한 NGINX Plus 변수의 값을 포함한 해당 요청에 대한 세부 정보를 볼 수 있습니다.

캐싱을 사용한 응답 시간 추적

NGINX Plus 캐싱 구성

NGINX Plus 구성 에서 생성한 opentracing.conf 파일에 지침을 추가하여 캐싱을 활성화합니다.

  1. http 컨텍스트에서 이 proxy_cache_path 지시문을 추가합니다.

    프록시_캐시_경로 /data/nginx/캐시 키_존=one:10m;
  2. 서버 블록에서 다음 proxy_cacheproxy_cache_valid 지침을 추가합니다.

    proxy_cache 1;
    proxy_cache_valid 임의 1m;
  3. 구성을 검증하고 다시 로드합니다.

    $ nginx -t $ nginx -s 다시로드

Caching을 사용한 Jaeger의 출력

두 가지 요청 후 Jaeger UI는 다음과 같습니다.

첫 번째 응답( 13f69db 로 표시)에는 4초가 걸렸습니다. NGINX Plus는 응답을 캐시했으며, 약 15초 후에 요청이 반복되었을 때 응답은 NGINX Plus 캐시에서 나왔기 때문에 2밀리초(ms)도 걸리지 않았습니다.

두 요청을 자세히 살펴보면 응답 시간의 차이를 알 수 있습니다. 첫 번째 요청의 경우 upstream_cache_statusMISS 입니다. 즉, 요청된 데이터가 캐시에 없었습니다. Ruby 앱은 4초의 지연을 추가했습니다.

두 번째 요청의 경우 upstream_cache_statusHIT 입니다. 데이터가 캐시에서 나오기 때문에 Ruby 앱은 지연을 추가할 수 없으며 응답 시간은 2ms 미만입니다. 빈 upstream_* 값은 업스트림 서버가 이 응답에 관여하지 않았음을 나타냅니다.

캐싱을 사용한 Zipkin의 출력

캐싱이 활성화된 두 요청에 대한 Zipkin UI의 표시는 비슷한 그림을 그립니다.

그리고 두 요청을 자세히 살펴보면 응답 시간의 차이가 설명됩니다. 첫 번째 요청( upstream_cache_statusMISS 임)의 응답은 캐시되지 않았고 Ruby 앱은 우연히 Jaeger 예제와 동일한 4초 지연을 추가합니다.

두 번째 요청을 하기 전에 응답이 캐시되었으므로 upstream_cache_statusHIT 입니다.

결론

NGINX OpenTracing 모듈은 NGINX Plus 요청과 응답을 추적하고 OpenTracing 태그를 사용하여 NGINX Plus 변수에 대한 액세스를 제공합니다. 이 모듈에는 다양한 추적기도 사용할 수 있습니다.

NGINX OpenTracing 모듈에 대한 자세한 내용은 GitHub의 NGINX OpenTracing 모듈 리포를 방문하세요.

NGINX Plus에서 OpenTracing을 사용해 보려면 오늘 무료 30일 평가판을 시작하거나 저희에게 문의하여 사용 사례에 대해 논의하세요 .


"이 블로그 게시물에는 더 이상 사용할 수 없거나 더 이상 지원되지 않는 제품이 참조될 수 있습니다. 사용 가능한 F5 NGINX 제품과 솔루션에 대한 최신 정보를 보려면 NGINX 제품군을 살펴보세요. NGINX는 이제 F5의 일부가 되었습니다. 이전의 모든 NGINX.com 링크는 F5.com의 유사한 NGINX 콘텐츠로 리디렉션됩니다."