문제해결

Pub/Sub 사용 중에 문제가 발생할 경우 유용하게 활용할 수 있는 문제해결 단계를 알아봅니다.

구독 생성 불가

다음을 완료했는지 확인합니다.

  • name 필드에 구독 이름을 지정했습니다. v1beta2 버전 이상인 경우 구독 이름은 projects/project-identifier/subscriptions/subscription-name 형식이어야 합니다.
  • topic 필드에 구독하려는 기존 주제의 이름을 지정했습니다. v1beta2 버전 이상인 경우 주제 이름은 projects/project-identifier/topics/topic-name 형식이어야 합니다.
  • pushEndpoint 필드에 수신 URL의 프로토콜로 (http:// 또는HTTPS://가 아닌) https://를 소문자로 지정했습니다.

403 (Forbidden) 오류

이 오류가 발생한다면 다음을 수행하세요.

  • Google Cloud Console에서 Pub/Sub API를 사용 설정했는지 확인합니다.
  • 특히 프로젝트 간 통신에 Pub/Sub API를 사용하는 경우, 요청을 수행하는 주체가 관련 Pub/Sub API 리소스에 필요한 권한을 갖고 있는지 확인합니다.
  • Dataflow를 사용하는 경우 <projectId>@cloudservices.gserviceaccount.com 및 Compute Engine 서비스 계정 <projectId>-compute@developer.gserviceaccount.com에 모두 관련 Pub/Sub API 리소스에 대한 필수 권한이 있는지 확인합니다. 자세한 내용은 Dataflow 보안 및 권한을 참조하세요.
  • App Engine을 사용한다면 프로젝트의 권한 페이지를 확인해 App Engine 서비스 계정이 편집자로 표시되어 있는지 살펴봅니다. 그렇지 않다면 App Engine 서비스 계정을 편집자로 추가해야 합니다. 일반적으로 App Engine 서비스 계정은 <project-id>@appspot.gserviceaccount.com 형식입니다.

중복 처리 및 강제 재시도

확인 기한이 만료되기 전에 메시지를 확인하지 않으면 Pub/Sub에서 메시지를 다시 보냅니다. 따라서 Pub/Sub는 중복 메시지를 보낼 수 있습니다. Cloud Monitoring을 사용하여 이 상태를 감지하는 expired 응답 코드로 확인 작업을 모니터링하세요. 이 데이터를 가져오려면 subscription/expired_ack_deadlines_count 측정항목을 선택합니다.

Cloud Monitoring을 사용하여 만료된 메시지 확인 기한 검색

중복률을 줄이려면 메시지 기한을 연장하세요.

  • 클라이언트 라이브러리는 기한 연장을 자동으로 처리하지만, 구성할 수 있는 최대 연장 기한에 기본 한도가 있습니다.
  • 자체 클라이언트 라이브러리를 빌드하는 경우 modifyAckDeadline 메서드를 사용하여 확인 기한을 연장합니다.

또는 Pub/Sub가 메시지를 다시 시도하도록 하려면 modifyAckDeadline을 0으로 설정하세요.

과도한 관리 작업 사용

관리 작업에 할당량을 너무 많이 사용하고 있는 경우 코드를 리팩토링해야 할 수도 있습니다. 다음 유사 코드를 예로 들어 보겠습니다. 이 예에서는 리소스를 소모하기 전에 관리 작업(GET)을 사용하여 구독이 있는지 확인합니다. GETCREATE 모두 다음과 같은 관리 작업입니다.


    if !GetSubscription my-sub {
     CreateSubscription my-sub
    }
    Consume from subscription my-sub
            

보다 효율적인 패턴은 구독에서 메시지를 소비하려고 시도하는 것입니다(구독 이름을 합리적으로 확신할 수 있다고 가정). 이 낙관적 접근 방식에서는 오류가 있는 경우에만 구독을 가져오거나 생성합니다. 다음 예시를 참조하세요.

    try {
      Consume from subscription my-sub
    } catch NotFoundError {
      CreateSubscription my-sub
      Consume from subscription my-sub
    }