이는 NGINX 오픈 소스와 NGINX Plus를 API 게이트웨이로 배포하는 방법에 대한 시리즈의 세 번째 블로그 게시물입니다.
메모: 별도로 명시된 경우를 제외하고 이 게시물의 모든 정보는 NGINX Plus와 NGINX Open Source에 모두 적용됩니다. 읽기 편하도록 나머지 블로그에서는 논의가 두 버전에 모두 적용될 경우 간단히 "NGINX"라고 언급합니다.
마이크로서비스 애플리케이션 아키텍처의 개념과 이점은 최근 몇 년 동안 잘 문서화되어 왔으며, NGINX 블로그 보다 더 자세히 알려진 곳은 없습니다. 마이크로서비스 애플리케이션의 핵심은 HTTP API이며, 이 시리즈의 처음 두 블로그 게시물에서는 가상의 REST API를 사용하여 NGINX가 이러한 스타일의 애플리케이션을 어떻게 처리하는지 설명합니다.
최신 애플리케이션에서 JSON 메시지 형식을 갖춘 REST API가 인기를 끌고 있지만, 이는 모든 시나리오 또는 모든 조직에 이상적인 접근 방식은 아닙니다. 가장 흔한 과제는 다음과 같습니다.
최근 몇 년 동안 gRPC는 분산 애플리케이션, 특히 마이크로서비스 애플리케이션을 구축하는 대안적인 접근 방식으로 떠올랐습니다. gRPC는 원래 Google에서 개발되었으나 2015년에 오픈 소스로 공개되었으며, 현재는 Cloud Native Computing Foundation의 프로젝트 입니다. 중요한 점은 gRPC가 HTTP/2를 전송 메커니즘으로 사용하여 이진 데이터 형식과 다중화 스트리밍 기능을 활용한다는 것입니다.
gRPC의 주요 이점은 다음과 같습니다.
이 시리즈의 처음 두 게시물에서는 여러 API가 단일 진입점(예: https://api.example.com )을 통해 제공되는 방법을 설명했습니다. gRPC 트래픽의 기본 동작과 특성으로 인해 NGINX를 gRPC 게이트웨이로 배포하는 경우에도 동일한 접근 방식을 취하게 됩니다. 동일한 호스트 이름과 포트에서 HTTP와 gRPC 트래픽을 모두 공유하는 것이 가능하지만, 이를 분리하는 것이 더 바람직한 데에는 여러 가지 이유가 있습니다.
이러한 분리를 달성하기 위해 gRPC 게이트웨이에 대한 구성을 /etc/nginx/conf.d 디렉토리에 있는 주 gRPC 구성 파일인 grpc_gateway.conf 의 자체 server{}
블록에 넣었습니다.
먼저 gRPC 트래픽에 대한 액세스 로그 의 항목 형식을 정의합니다(1~4행). 이 예에서는 JSON 형식을 사용하여 각 요청에서 가장 관련성 있는 데이터를 수집합니다. 예를 들어, 모든 gRPC 요청이 POST를
사용하므로 HTTP 메서드는 포함되지 않습니다. HTTP 상태 코드와 함께 gRPC 상태 코드도 기록합니다. 하지만 gRPC 상태 코드는 다양한 방법으로 생성될 수 있습니다. 일반적인 조건에서 grpc-status는
백엔드에서 HTTP/2 트레일러로 반환되지만, 일부 오류 조건에서는 백엔드나 NGINX 자체에서 HTTP/2 헤더로 반환될 수 있습니다. 액세스 로그를 단순화하기 위해 맵
블록(6~9행)을 사용하여 새 변수 $grpc_status를
평가하고 해당 변수가 어디에서 왔든 gRPC 상태를 가져옵니다.
이 구성에는 두 개의 수신
지시문(12번째 줄과 13번째 줄)이 포함되어 있어서 일반 텍스트(포트 50051)와 TLS로 보호된(포트 443) 트래픽을 모두 테스트할 수 있습니다. http2
매개변수는 NGINX가 HTTP/2 연결을 허용하도록 구성합니다. 이것은 ssl
매개변수와 독립적입니다. 또한 포트 50051은 gRPC의 기존 평문 포트이지만 프로덕션에서 사용하기에는 적합하지 않습니다.
TLS 구성은 일반적인 구성이며, ssl_protocols
지시어(23번째 줄)에서는 TLS 1.2를 허용 가능한 가장 약한 프로토콜로 지정합니다. HTTP/2 사양에서는 TLS 1.2(또는 그 이상)를 사용하도록 규정하고 있으며 , 이를 통해 모든 클라이언트가 TLS에 대한 SNI( 서버 이름 표시 ) 확장을 지원하도록 보장합니다. 즉, gRPC 게이트웨이는 다른 server{}
블록에 정의된 가상 서버와 포트 443을 공유할 수 있습니다.
NGINX의 gRPC 기능을 살펴보기 위해 여러 gRPC 서비스가 배포된 gRPC 게이트웨이의 핵심 구성 요소를 나타내는 간단한 테스트 환경을 사용합니다. 우리는 공식 gRPC 가이드 의 두 가지 샘플 애플리케이션을 사용합니다: helloworld (Go로 작성)와 RouteGuide (Python으로 작성). RouteGuide 애플리케이션은 네 가지 gRPC 서비스 방법을 모두 포함하고 있기 때문에 특히 유용합니다.
두 gRPC 서비스는 모두 NGINX 호스트에 Docker 컨테이너로 설치되었습니다. 테스트 환경을 구축하는 방법에 대한 자세한 지침은 부록을 참조하세요.
RouteGuide 및 helloworld 서비스와 사용 가능한 컨테이너의 주소를 알 수 있도록 NGINX를 구성합니다.
각 gRPC 서비스에 대한 업스트림
블록을 추가하고(40~45행과 47~51행) gRPC 서버 코드를 실행하는 개별 컨테이너의 주소로 채웁니다.
NGINX가 gRPC의 기존 일반 텍스트 포트(50051)를 수신하고 구성에 라우팅 정보를 추가하여 클라이언트 요청이 올바른 백엔드 서비스에 도달하도록 합니다. 하지만 먼저 gRPC 메서드 호출이 HTTP/2 요청으로 어떻게 표현되는지 이해해야 합니다. 다음 다이어그램은 RouteGuide 서비스의 route_guide.proto 파일의 축약 버전을 보여주며, NGINX에서 보는 바와 같이 패키지, 서비스 및 RPC 메서드가 URI를 형성하는 방식을 설명합니다.
따라서 HTTP/2 요청에 포함된 정보는 패키지 이름(여기서는 routeguide
또는 helloworld
)만 일치시키면 라우팅 목적으로 사용할 수 있습니다.
첫 번째 위치
블록(26번째 줄)은 수정자 없이 접두사 일치를 정의하여 /routeguide가
해당 패키지의 .proto 파일에 정의된 모든 서비스 및 RPC 메서드와 일치하도록 합니다. 따라서 grpc_pass
지시어(27번째 줄)는 RouteGuide 클라이언트의 모든 요청을 상위 그룹 routeguide_service 로 전달합니다. 이 구성(29, 30번째 줄의 helloworld 서비스에 대한 병렬 구성)은 gRPC 패키지와 백엔드 서비스 간의 간단한 매핑을 제공합니다.
grpc_pass
지시어에 대한 인수는 grpc://
스키마로 시작하는데, 이는 일반 텍스트 gRPC 연결을 사용하여 요청을 프록시합니다. 백엔드가 TLS로 구성된 경우 grpcs://
체계를 사용하여 종단 간 암호화로 gRPC 연결을 보호할 수 있습니다.
RouteGuide 클라이언트를 실행한 후 로그 파일 항목을 검토하여 라우팅 동작을 확인할 수 있습니다. 여기서는 RouteChat RPC 메서드가 포트 10002에서 실행되는 컨테이너로 라우팅된 것을 볼 수 있습니다.
$ 파이썬 route_guide_client.py ... $ tail -1 /var/log/nginx/grpc_log.json | jq { "타임스탬프": "2021-01-20T12:17:56+01:00", "클라이언트": "127.0.0.1", "uri": "/routeguide.RouteGuide/RouteChat", "http-상태": 200, "grpc-상태": 0, "상류": "127.0.0.1:10002", "수신 바이트": 161, "tx-바이트": 212 }
위에서 보인 것처럼, 여러 gRPC 서비스를 서로 다른 백엔드로 라우팅하는 것은 간단하고 효율적이며, 구성 줄도 거의 필요하지 않습니다. 그러나 프로덕션 환경에서의 라우팅 요구 사항은 더 복잡할 수 있으며 URI의 다른 요소(gRPC 서비스 또는 개별 RPC 메서드)를 기반으로 하는 라우팅이 필요할 수 있습니다.
다음 구성 스니펫은 이전 예제를 확장하여 양방향 스트리밍 RPC 메서드 RouteChat이
한 백엔드로 라우팅되고 다른 모든 RouteGuide
메서드는 다른 백엔드로 라우팅되도록 합니다.
두 번째 위치
지시문(7번째 줄)은 =
(등호) 수정자를 사용하여 이것이 RouteChat
RPC 메서드의 URI와 정확하게 일치함을 나타냅니다. 정확한 일치는 접두사 일치보다 먼저 처리되므로 RouteChat
URI에 대해 다른 위치
블록은 고려되지 않습니다.
gRPC 오류는 기존 HTTP 트래픽의 오류와 다소 다릅니다. 클라이언트는 오류 조건이 gRPC 응답으로 표현되기를 기대하므로 NGINX가 gRPC 게이트웨이로 구성된 경우 기본 NGINX 오류 페이지 세트(HTML 형식)는 적합하지 않습니다. 우리는 gRPC 클라이언트에 대한 사용자 정의 오류 응답 세트를 지정하여 이 문제를 해결합니다.
gRPC 오류 응답의 전체 세트는 비교적 길고 대부분 정적인 구성이므로 이를 별도의 파일인 errors.grpc_conf 에 보관하고 include
지시문(34번째 줄)을 사용하여 참조합니다. HTTP/REST 클라이언트와 달리 gRPC 클라이언트 애플리케이션은 광범위한 HTTP 상태 코드를 처리할 것으로 예상되지 않습니다. gRPC 문서에서는 NGINX와 같은 중간 프록시가 클라이언트가 항상 적절한 응답을 받을 수 있도록 HTTP 오류 코드를 gRPC 상태 코드로 변환해야 하는 방법을 지정합니다. 이 매핑을 수행하려면 error_page
지시문을 사용합니다.
각 표준 HTTP 상태 코드는 @
접두사를 사용하여 명명된 위치로 전달되므로 gRPC 호환 응답을 생성할 수 있습니다. 예를 들어, HTTP404
응답은 내부적으로 @grpc_unimplemented
위치로 리디렉션됩니다. 이 위치는 파일에서 나중에 정의됩니다.
@grpc_unimplemented
라는 명명된 위치는 내부 NGINX 처리에만 사용할 수 있습니다. 라우팅 가능한 URI가 없기 때문에 클라이언트가 직접 요청할 수 없습니다. 이 위치 내에서 필수 gRPC 헤더를 채우고 응답 본문 없이 HTTP 상태 코드를 사용하여 이를 전송하여 gRPC 응답을 구성합니다.204
( 내용
없음
).
curl(1)
명령을 사용하면 존재하지 않는 gRPC 메서드를 요청하는 잘못된 동작의 gRPC 클라이언트를 모방할 수 있습니다. 그러나 프로토콜 버퍼는 이진 데이터 형식을 사용하기 때문에 curl
은 일반적으로 gRPC 테스트 클라이언트로 적합하지 않습니다. 명령줄에서 gRPC를 테스트하려면 grpc_cli 를
사용해 보세요.
$ curl -i --http2 -H "콘텐츠 유형: application/grpc" -H "TE: 트레일러" -X POST https://grpc.example.com/does.Not/Exist HTTP/2 204 서버: nginx/1.19.5 날짜: 수, 2021년 1월 20일 15:03:41 GMT grpc-status: 12 grpc-message: 구현되지 않음
위에 참조된 grpc_errors.conf 파일에는 NGINX가 생성할 수 있는 시간 초과 및 클라이언트 인증서 오류와 같은 다른 오류 응답에 대한 HTTP‑gRPC 상태 코드 매핑도 포함되어 있습니다.
gRPC 메타데이터를 사용하면 클라이언트가 프로토콜 버퍼 사양( .proto 파일)에 데이터가 포함될 필요 없이 RPC 메서드 호출과 함께 추가 정보를 보낼 수 있습니다. 메타데이터는 키-값 쌍의 간단한 목록이며, 각 쌍은 별도의 HTTP/2 헤더로 전송됩니다. 따라서 NGINX에서 메타데이터에 쉽게 접근할 수 있습니다.
메타데이터의 많은 사용 사례 중에서 클라이언트 인증은 gRPC API 게이트웨이에서 가장 일반적입니다. 다음 구성 스니펫은 NGINX Plus가 gRPC 메타데이터를 사용하여 JWT 인증을 수행하는 방법을 보여줍니다(JWT 인증은 NGINX Plus에서만 사용 가능). 이 예에서 JWT는 인증 토큰
메타데이터를 통해 전송됩니다.
모든 HTTP 요청 헤더는 NGINX Plus에서 $http_ header
라는 변수로 사용할 수 있습니다. 헤더 이름의 하이픈( -
)은 변수 이름에서는 밑줄( _
)로 변환되므로 JWT를 $http_auth_token
(2번째 줄)으로 사용할 수 있습니다.
API 키가 인증에 사용되는 경우, 아마도 기존 HTTP/REST API와 함께 사용되는 경우, 이러한 키는 gRPC 메타데이터에 포함되어 NGINX에서 검증될 수도 있습니다. API 키 인증<.htmla>에 대한 구성은 이 블로그 시리즈의 1부에 제공됩니다.
여러 백엔드로 트래픽 부하를 분산할 때 다운되었거나 사용할 수 없는 백엔드로 요청을 보내지 않는 것이 중요합니다. NGINX Plus를 사용하면 활성 상태 검사를 사용하여 백엔드에 대역 외 요청을 사전에 보내고 예상대로 상태 검사에 응답하지 않으면 부하 분산 로테이션에서 제거할 수 있습니다. 이런 식으로 클라이언트 요청이 서비스가 중단된 백엔드에 도달하는 일이 없도록 보장합니다.
다음 구성 스니펫은 RouteGuide 및 helloworld gRPC 서비스에 대한 활성 상태 검사를 활성화합니다. 관련 구성을 강조하기 위해 이전 섹션에서 사용된 grpc_gateway.conf 파일에 포함된 일부 지시문을 생략합니다.
이제 각 경로에 대해 health_check
지시어(17번째 줄과 21번째 줄)도 지정합니다. type=grpc
인수에서 지정한 대로 NGINX Plus는 gRPC 상태 검사 프로토콜을 사용하여 업스트림 그룹의 모든 서버에 상태 검사를 보냅니다. 그러나 우리의 간단한 gRPC 서비스는 gRPC 상태 검사 프로토콜을 구현하지 않으므로 "구현되지 않음"( grpc_status=12
)을 의미하는 상태 코드로 응답할 것으로 예상합니다. 그렇다면 그것은 우리가 활성 gRPC 서비스와 통신하고 있다는 것을 나타내기에 충분합니다.
이 구성을 적용하면 gRPC 클라이언트가 지연이나 시간 초과를 경험하지 않고 백엔드 컨테이너를 모두 중단할 수 있습니다. 활성 상태 검사는 NGINX Plus에서만 제공됩니다. 블로그에서 gRPC 상태 검사 에 대해 자세히 알아보세요.
grpc_gateway.conf 의 샘플 구성은 TLS에 대한 몇 가지 사소한 수정을 거쳐 프로덕션 사용에 적합합니다. 패키지, 서비스 또는 RPC 방법에 따라 gRPC 요청을 라우팅하는 기능은 기존 NGINX 기능을 HTTP/REST API나 일반 웹 트래픽과 똑같은 방식으로 gRPC 트래픽에 적용할 수 있음을 의미합니다. 각각의 경우에, 관련 위치
블록은 속도 제한이나 대역폭 제어와 같은 추가 구성을 통해 확장될 수 있습니다.
NGINX 오픈 소스와 NGINX Plus를 API 게이트웨이로 배포하는 것에 대한 시리즈의 세 번째이자 마지막 블로그 게시물에서는 마이크로서비스 애플리케이션을 구축하기 위한 클라우드 기반 기술인 gRPC에 초점을 맞추었습니다. 우리는 NGINX가 HTTP/REST API와 마찬가지로 효과적으로 gRPC 애플리케이션을 제공하는 방법과 두 가지 스타일의 API가 모두 다목적 API 게이트웨이인 NGINX를 통해 게시될 수 있는 방법을 시연했습니다.
이 블로그 게시물에 사용된 테스트 환경을 설정하는 방법에 대한 지침은 아래 부록 에 나와 있으며, GitHub Gist repo 에서 모든 파일을 다운로드할 수 있습니다.
이 시리즈의 다른 블로그 게시물을 확인하세요.
NGINX Plus를 API 게이트웨이로 사용해 보려면 오늘 무료 30일 평가판을 시작하거나 당사에 문의하여 사용 사례에 대해 논의해 보세요 . 평가판 사용 기간 동안 GitHub Gist repo 에서 전체 구성 파일 세트를 사용하세요.
다음 지침에서는 가상 머신에 테스트 환경을 설치하여 격리하고 반복 가능하도록 합니다. 하지만 물리적인 "베어 메탈" 서버에 설치하지 못할 이유는 없습니다.
테스트 환경을 단순화하기 위해 Docker 컨테이너를 사용하여 gRPC 서비스를 실행합니다. 즉, 테스트 환경에 여러 호스트가 필요하지 않지만 프로덕션 환경처럼 NGINX가 네트워크 호출을 통해 프록시 연결을 만들 수 있습니다.
Docker를 사용하면 코드를 변경하지 않고도 다른 포트에서 각 gRPC 서비스의 여러 인스턴스를 실행할 수 있습니다. 각 gRPC 서비스는 가상 머신의 고유한 로컬호스트 포트에 매핑된 컨테이너 내의 포트 50051에서 수신합니다. 이렇게 하면 포트 50051이 해제되어 NGINX가 이를 수신 포트로 사용할 수 있습니다. 따라서 테스트 클라이언트가 미리 구성된 포트 50051을 사용하여 연결하면 NGINX에 도달합니다.
NGINX Plus 관리자 가이드의 지침에 따라 NGINX Open Source 또는 NGINX Plus를 설치하세요.
다음 파일을 GitHub Gist repo 에서 /etc/nginx/conf.d 로 복사합니다.
메모: TLS를 사용하지 않는 경우 grpc_gateway.conf 에서 ssl_*
지침을 주석으로 처리합니다.
NGINX Open Source 또는 NGINX Plus를 시작하세요.
$ sudo nginx
Debian 및 Ubuntu의 경우 다음을 실행하세요.
$ sudo apt-get docker.io 설치
CentOS, RHEL 및 Oracle Linux의 경우 다음을 실행하세요.
$ sudo yum docker 설치
다음 Dockerfile에서 RouteGuide 컨테이너에 대한 Docker 이미지를 빌드합니다.
빌드 전에 Dockerfile을 로컬 하위 디렉토리에 복사하거나, docker
build
명령의 인수로 Dockerfile의 Gist URL을 지정할 수 있습니다.
$ sudo docker build -t routeguide https://gist.githubusercontent.com/nginx-gists/87ed942d4ee9f7e7ebb2ccf757ed90be/raw/ce090f92f3bbcb5a94bbf8ded4d597cd47b43cbe/routeguide.Dockerfile
이미지를 다운로드하고 빌드하는 데 몇 분이 걸릴 수 있습니다. 성공적으로
빌드되었습니다라는
메시지와 16진수 문자열(이미지 ID)이 나타나면 빌드가 완료되었음을 나타냅니다.
docker
images를
실행하여 이미지가 빌드되었는지 확인합니다.
$ sudo docker images 저장소 태그 이미지 ID 생성 크기 routeguide 최신 63058a1cf8ca 1분 전 1.31GB python 최신 825141134528 9일 전 923MB
RouteGuide 컨테이너를 시작합니다.
$ sudo docker run --name rg1 -p 10001:50051 -d 경로 가이드 $ sudo docker run --name rg2 -p 10002:50051 -d 경로 가이드 $ sudo docker run --name rg3 -p 10003:50051 -d 경로 가이드
각 명령이 성공하면 실행 중인 컨테이너를 나타내는 긴 16진수 문자열이 나타납니다.
docker
ps 를
실행하여 세 개의 컨테이너가 모두 작동 중인지 확인하세요. (샘플 출력은 읽기 편하도록 여러 줄로 나뉩니다.)
$ sudo docker ps 컨테이너 ID 이미지 명령 상태 ... d0cdaaeddf0f routeguide "python route_g..." 2초 전... c04996ca3469 routeguide "python route_g..." 9초 전...
2170ddb62898 경로 가이드 "파이썬 route_g..." 1분 전 ... ... 항구 이름 ... 다음 명령은 TCP/IP 네트워크에서 패킷을 수신하는 데 사용됩니다. 0.0.0.0:10002->50051/tcp rg2 ... 0.0.0.0:10001->50051/tcp rg1
출력에서 PORTS
열은 각 컨테이너가 어떻게 다른 로컬 포트를 컨테이너 내부의 포트 50051에 매핑했는지 보여줍니다.
다음 Dockerfile에서 helloworld 컨테이너에 대한 Docker 이미지를 빌드합니다.
빌드 전에 Dockerfile을 로컬 하위 디렉토리에 복사하거나, docker
build
명령의 인수로 Dockerfile의 Gist URL을 지정할 수 있습니다.
$ sudo docker build -t helloworld https://gist.githubusercontent.com/nginx-gists/87ed942d4ee9f7e7ebb2ccf757ed90be/raw/ce090f92f3bbcb5a94bbf8ded4d597cd47b43cbe/helloworld.Dockerfile
이미지를 다운로드하고 빌드하는 데 몇 분이 걸릴 수 있습니다. 성공적으로
빌드되었습니다라는
메시지와 16진수 문자열(이미지 ID)이 나타나면 빌드가 완료되었음을 나타냅니다.
docker
images를
실행하여 이미지가 빌드되었는지 확인합니다.
$ sudo docker images 저장소 태그 이미지 ID 생성 크기 helloworld 최신 e5832dc0884a 10초 전 926MB routeguide 최신 170761fa3f03 4분 전 1.31GB python 최신 825141134528 9일 전 923MB golang 최신 d0e7a411e3da 3주 전 794MB
Helloworld 컨테이너를 시작합니다.
$ sudo docker run --name hw1 -p 20001:50051 -d helloworld $ sudo docker run --name hw2 -p 20002:50051 -d helloworld
각 명령이 성공하면 실행 중인 컨테이너를 나타내는 긴 16진수 문자열이 나타납니다.
docker
ps 를
실행하여 두 개의 helloworld 컨테이너가 작동 중인지 확인합니다.
$ sudo docker ps 컨테이너 ID 이미지 명령 상태 ... e0d204ae860a helloworld "go run greeter..." 5초 전...
66f21d89be78 helloworld "가서 인사해줘..." 9초 남았습니다... d0cdaaeddf0f routeguide "python route_g..." 4분 남았습니다... c04996ca3469 routeguide "python route_g..." 4분 전 ...
2170ddb62898 경로 가이드 "파이썬 route_g..." 5분 전 ... ... 항구 이름 ... 0.0.0.0:20002->50051/tcp hw2 ... 0.0.0.0:20001->50051/tcp hw1 ... 다음 명령은 TCP/IP 네트워크에서 패킷을 수신하는 데 사용됩니다. 0.0.0.0:10002->50051/tcp rg2 ... 0.0.0.0:10001->50051/tcp rg1
프로그래밍 언어 필수 구성 요소를 설치합니다. 이 중 일부는 테스트 환경에 이미 설치되어 있을 수 있습니다.
Ubuntu 및 Debian의 경우 다음을 실행하세요.
$ sudo apt-get 설치 golang-go python3 python-pip git
CentOS, RHEL 및 Oracle Linux의 경우 다음을 실행하세요.
$ sudo yum 설치 golang python python-pip git
python-pip를
사용하려면 EPEL 저장소가 활성화되어 있어야 합니다(필요한 경우 먼저 sudo
yum
install
epel-release를
실행하세요).
Helloworld 애플리케이션을 다운로드하세요:
$ google.golang.org/grpc를 받으세요
RouteGuide 애플리케이션을 다운로드하세요:
$ git clone -b v1.14.1 https://github.com/grpc/grpc $ pip install grpcio-tools
Helloworld 클라이언트를 실행합니다.
$ go 실행 go/src/google.golang.org/grpc/examples/helloworld/greeter_client/main.go
RouteGuide 클라이언트를 실행합니다.
$ cd grpc/examples/python/route_guide $ python route_guide_client.py
테스트 환경이 작동하는지 확인하려면 NGINX 로그를 확인하세요.
$ tail /var/log/nginx/grpc_log.json
"이 블로그 게시물에는 더 이상 사용할 수 없거나 더 이상 지원되지 않는 제품이 참조될 수 있습니다. 사용 가능한 F5 NGINX 제품과 솔루션에 대한 최신 정보를 보려면 NGINX 제품군을 살펴보세요. NGINX는 이제 F5의 일부가 되었습니다. 이전의 모든 NGINX.com 링크는 F5.com의 유사한 NGINX 콘텐츠로 리디렉션됩니다."