글 / gRPC 통신

Grpcurl을 이용한 gRPC 서버 점검

서버에 리플렉션을 활성화하면 Proto 파일 없이 Grpcurl로 목록을 조회하고 JSON으로 호출할 수 있다.

작성일 · 읽는 시간 3분 · Grpcurl 1.9 기준

Proto 없는 점검

gRPC는 protobuf 바이너리를 송수신하므로 curl로는 요청을 구성하기 어렵다. grpcurl은 JSON으로 작성한 요청을 받아 gRPC로 호출한다. 이를 위해서는 메시지 구조를 알아야 하는데, 서버가 리플렉션(reflection, 서버가 자신의 서비스 정의를 제공하는 기능)을 활성화하면 grpcurl이 서버에서 직접 조회한다.

grpcurl이 리플렉션으로 구조를 조회하고 호출하는 구성

리플렉션 활성화

리플렉션은 기본적으로 비활성화되어 있다. Python에서는 grpcio-reflection 패키지를 설치하고, 서버를 시작하기 전에 등록한다.

pythonserver.py
from grpc_reflection.v1alpha import reflection

import status_pb2


def enable_reflection(server):
    # 내 서비스와 리플렉션 서비스의 이름을 함께 등록한다
    names = (
        status_pb2.DESCRIPTOR.services_by_name["StatusService"].full_name,
        reflection.SERVICE_NAME,
    )
    reflection.enable_server_reflection(names, server)

목록, 구조, 호출

bash
# 서비스 목록
grpcurl -plaintext localhost:50051 list
# 한 서비스의 메서드 목록
grpcurl -plaintext localhost:50051 list device.v1.StatusService
# 메서드나 메시지의 정의
grpcurl -plaintext localhost:50051 describe device.v1.StatusRequest
# 호출
grpcurl -plaintext -d '{"device_id": "d-01"}' \
  localhost:50051 device.v1.StatusService/GetStatus

grpcurl의 목록·구조 조회와 호출의 요청·응답 순서

  • -plaintext: TLS 없이 접속한다. TLS 서버에는 이 옵션을 지정하지 않는다.
  • -d: 요청 본문 JSON이다. -d @는 표준 입력에서 읽는다.
  • -H: 메타데이터(헤더)를 이름:값 형식으로 추가한다.

옵션은 모두 서버 주소 앞에 지정한다.

리플렉션 비활성 환경

proto 파일을 직접 지정한다. 외부에 공개된 서버에서는 리플렉션이 API 구조를 그대로 노출하므로, 리플렉션을 비활성화하고 이 방식을 사용한다.

리플렉션 활성 환경과 비활성 환경의 점검 방식 비교

bash
grpcurl -plaintext -import-path ./protos -proto status.proto \
  -d '{"device_id": "d-01"}' localhost:50051 device.v1.StatusService/GetStatus