>

파이썬에서 grpc-gateway 뒤에 grpc 서비스를 작성 중이며 일부 사용자의 요청이 너무 많은 경우 429 응답을 발생시키고 응답 메시지 본문에 보안 문자 토큰을 제공하려고합니다.

실제로 내 문제는 아래 코드 블록을 사용하여 상태 코드 429를 올리면 응답 메시지를 보낼 수 없다는 것입니다.

context.set_code(grpc.StatusCode.RESOURCE_EXHAUSTED)
context.set_details('Too many requests')
return MyServiceResponse()

단일 grpc로는 불가능하다는 것을 알았지 만 타사에서는 가능하다고 생각합니다.

이것에 대한 해결책이 있습니까?

  • 답변 # 1

    비 확인 상태로 응답을 보내는 것은 단항 단항 RPC (양쪽에서 비 스트리밍)에 허용되지 않습니다. 스트리밍 RPC의 경우 서버는 오류 코드를 보내기 전에 응답을 보낼 수 있지만 권장되지는 않습니다. 정상 응답과 오류 상태를 혼합하면 향후 유지 보수성 문제가 발생할 수 있습니다 (예 : 동일한 오류가 여러 RPC에 적용되는 경우 모든 응답 ProtoBuf 메시지에 해당 필드가 포함되어야합니까?

    질문으로 돌아가서 "자본 토큰"은 오류 상태의 일부로 간주되므로 후행 메타 데이터 중 하나로 추가 할 수 있습니다. 귀하의 경우 -bin 를 추가하여 직렬화 된 프로토 메시지를 이진 후행 메타 데이터로 추가 할 수 있습니다  후행 메타 데이터 키의 접미사

    또한 공식 지원 패키지 grpcio-status 가 있습니다  그게 당신을 위해이 일을합니다.

    서버 측은 풍부한 오류 상태를 "grpc_status.status_pb2.Status"프로토 메시지에 압축합니다. 아래 예제는 일반적인 오류 프로토만을 사용하지만 "any"프로토를 details 로 압축 할 수 있습니다 고객이 이해하는 한

    # Server side
    from grpc_status import rpc_status
    from google.protobuf import any_pb2
    def ...Servicer(...):
        def AnRPCCall(request, context):
            ...
            detail = any_pb2.Any()
            detail.Pack(
                rpc_status.error_details_pb2.DebugInfo(
                    stack_entries=traceback.format_stack(),
                    detail="Can't recognize this argument",
                )
            )
            rich_status = grpc_status.status_pb2.Status(
                code=grpc_status.code_pb2.INVALID_ARGUMENT,
                message='Invalid argument',
                details=[detail]
            )
            context.abort_with_status(rpc_status.to_status(rich_status))
            # The method handler will abort
    
    

    클라이언트 측에서 오류를 해독하고 이에 대해 반응합니다.

    # Client side
    try:
        self._channel.unary_unary(_ERROR_DETAILS).with_call(_REQUEST)
    except grpc.RpcError as rpc_error:
        status = rpc_status.from_call(rpc_error)
        for detail in status.details:
            if detail.Is(error_details_pb2.DebugInfo.DESCRIPTOR):
                info = error_details_pb2.DebugInfo()
                detail.Unpack(info)
                # Handle the debug info
            elif detail.Is(OtherErrorProto.DESCRIPTOR):
                # Handle the other error proto
            else:
                # Handle unknown error
    
    
    

    풍부한 상태에 대해 자세히 알아보십시오 : https://github.com/grpc/proposal/blob/master/L44-python-rich-status.md

  • 이전 Jenkins Groovy에서 메소드를 전달하는 방법은 무엇입니까?
  • 다음 r - 모든 문자열"atribuição - "사이의 모든 것을 추출하십시오