속도 제한

전 세계 애드워즈 API 사용자에게 안정적인 서비스를 제공하기 위해 토큰 버킷 알고리즘을 사용하여 요청을 측정하고 QPS(초 당 쿼리) 비율을 확인하고 있습니다. 이는 악의적이거나 통제 불능의 소프트웨어가 애드워즈 API 서버를 방해하여 다른 사용자에게 영향을 미치는 것을 방지하기 위함입니다.

예를 들어 클라이언트 폭주로 수천 개의 스레드에서 동시에 실수로 애드워즈 API를 호출하는 경우, 애드워즈 API 서버는 이를 인식하고 RateExceededError를 반환하여 호출한 소프트웨어에게 속도를 줄이도록 요청합니다.

일반적으로 속도 제한은 서버 부하를 비롯한 다양한 변수에 따라 변동이 있습니다. 따라서 개발자는 고정된 QPS 제한하지 않는 것이 좋습니다. RateExceededError를 처리하는 방법을 이해하고 속도 제한을 고려해 소프트웨어를 개발하는 것이 매우 중요합니다.

이 가이드에서는 RateExceededError를 이해하고 속도 제한을 초과하지 않는 방법에 대해 자세하게 설명합니다.

기존 방법

이전의 애드워즈 API 버전에서는 API 서버에서 한도를 초과한 요청은 요청이 실행될 때까지 대기 중이므로 일부 요청의 경우 실행 시간이 매우 길었습니다. 현재 API에서는 클라이언트를 오랜 시간동안 차단하는 대신 빨리 실패시켜 RateExceededError를 반환합니다. 이는 개발자가 문제를 인식하고 애플리케이션을 올바르게 조정할 수 있는 중요한 피드백 메커니즘입니다.

속도 제한의 종류

애드워즈 API 클라이언트 애플리케이션은 때때로 제어할 수 없는 요인으로 인해 한도를 초과하여 RateExceededError가 발생할 수 있습니다. 하지만 이에 대한 벌칙은 없습니다. RateExceededError는 보통 일시적이며 활동이 없으면 30초 후에 자동으로 해결됩니다.

서버에서 여러 종류의 속도 제한을 적용할 수 있습니다. 클라이언트 애플리케이션은 MCC의 개발자 토큰 범위 또는 애드워즈 계정 범위 내에서 속도 제한을 초과할 수 있습니다. 각 범위 내에서 속도 제한은 엄격한 QPS(초 당 쿼리) 제한 대신, RPM(분 당 요청), OPM(분 당 작업) 및 다른 종류의 속도 제한에 따라 측정됩니다. 이렇게 하면 꾸준한 트래픽과 폭주하는 트래픽 모두 애드워즈 API로 허용됩니다. 범위와 속도 제한 이름이 모두 RateExceededError의 일부로 반환됩니다.

액세스 수준에 따른 작업 제한

액세스 수준에 따른 작업 제한은 변동이 없는 유일한 속도 제한 유형입니다. 액세스 수준에는 기본 및 표준의 두 가지 종류가 있습니다. 기본 액세스 수준은 일일 한도가 10,000개의 작업입니다. 새로 생성된 애드워즈 MCC 계정은 기본적으로 기본 액세스 수준이 할당됩니다. 일일 10,000개 이상의 작업을 실행하려는 경우, 애드워즈 API 표준 액세스 신청서를 완료하여 표준 액세스 수준을 신청할 수 있습니다. 위의 두 가지 액세스 수준에는 사용료가 부과되지 않습니다. 작업 수를 계산하는 방법을 확인하려면 속도 시트를 참고하세요.

작업 제한 이외의 다른 모든 속도 제한은 변동될 수 있습니다. 따라서 애플리케이션에서 RateExceededError를 처리하는 것이 중요합니다.

RateExceededError 이해

RateExceededError를 더 자세히 살펴보면 다음과 같은 세 가지의 매우 중요한 필드를 가집니다.

  • rateScope - 초과된 속도의 범위로, ACCOUNT 또는 DEVELOPER입니다.
  • rateName - 초과된 속도 제한의 이름입니다. 이 값의 예는 RequestsPerMinute입니다.
  • retryAfterSeconds - 애플리케이션이 요청을 다시 시도하기 전에 기다려야 하는 제안된 시간(단위:초)입니다. 이는 일반적으로 30이지만 애플리케이션은 이 필드에서 제공된 값을 사용해야 합니다.

대부분의 경우 retryAfterSeconds에 기초한 요청 재시도 및 조절을 사용하면 RateExceededError로부터 충분히 복구 가능합니다. 애플리케이션이 지속적으로 속도 제한을 초과하는 경우, 애플리케이션에서 조절 전략을 영구적으로 구현하려면 rateScope 및 rateName에 대해 이해해야 합니다.

계정 범위 및 개발자 범위

Rate Scope 값은 ACCOUNT 또는 DEVELOPER입니다. 이는 속도 제한이 애드워즈 계정 수준에서 초과되었는지 아니면 개발자 토큰 수준에서 초과되었는지를 나타냅니다.

개발자 토큰 속도 범위

애드워즈 API를 사용하기 위해 가입한 모든 애드워즈 MCC 계정은 단일 개발자 토큰을 가지고 있으며, 대부분의 요청은 해당 개발자 토큰과 연결되어 있습니다. 동일한 개발자 토큰을 사용한 모든 클라이언트 요청에 대한 통합 QPS가 특정 속도 제한을 초과하는 경우, 개발자 속도 범위를 나타내는 RateExceededError가 반환됩니다.

예를 들어 MCC 계정에서 100개의 애드워즈 계정을 관리하고, 동일한 개발자 토큰을 사용하는 여러 개의 클라이언트 소프트웨어 인스턴스가 여러 프로세스, 스레드 또는 시스템에 초당 수백개의 통합 요청을 만드는 경우, 클라이언트 소프트웨어에 개발자 토큰 속도 범위에 대한 RateExceededError가 발생할 수 있습니다.

계정 속도 범위

MCC에서 관리하는 단일 애드워즈 계정에서 동일한 애플리케이션이 초당 많은 개수의 요청을 만들면 애드워즈 API 서버에서 계정 범위 내에서 초과한 속도 제한에 대해 RateExceededError를 반환할 수 있습니다. 예를 들어 클라이언트 애플리케이션에서 여러 개의 스레드를 만들어 단일 애드워즈 계정에 대해 수많은 개수의 mutate 연산을 수행하면 이와 같은 상황이 발생할 수 있습니다.

요청에 사용된 개발자 토큰에 상관 없이 전체 계정 속도 범위의 해당 속도 제한은 단일 애드워즈 계정에 대한 모든 요청에서 측정됩니다.

예를 들어 5개의 다른 MCC에서 단일 애드워즈 계정을 관리하면 5개의 MCC에서 동일한 애드워즈 계정에 동시에 요청을 만들 수 있습니다. 단일 애드워즈 계정에 대해 5개의 MCC에서 통합된 QPS가 한도를 초과하는 경우, 클라이언트에서 계정 속도 범위에 RateExceededError가 발생할 수 있습니다.

속도 이름 및 중요성

속도 범위를 이해하는 것과 함께 초과한 속도 제한의 유형을 이해하는 것도 중요합니다. 속도 제한의 유형은 rateName 필드에 반환됩니다. 흔히 볼 수 있는 속도 제한의 이름은 다음과 같습니다.

  • RequestsPerMinute
  • OperationsPerMinute
요청과 작업의 차이

그러면 RequestsPerMinuteOperationsPerMinute의 차이는 무엇일까요? 모든 SOAP 서비스 호출은 요청으로 계산됩니다. 예를 들어 CampaignService.mutate(...)를 호출할 때마다 하나의 요청으로 계산됩니다. 그러나 mutate 요청의 경우 100개의 CampaignOperation을 전달하면 이는 100개의 작업으로 계산됩니다.

위의 예에서는 여러 개의 작업을 하나의 요청으로 통합하여 RequestPerMinute 속도 제한은 피할 수 있지만 OperationsPerMinute 속도 제한에 해당될 수 있습니다.

작업이 계산되는 방법에 대한 다른 예제는 속도 시트 페이지에서 찾을 수 있습니다.

특별한 경우

위의 속도 이름은 매우 잘 알려져 있지만, 초과할 수 있는 다른 유형의 속도 제한도 있을 수 있습니다. 이러한 문제가 발생하는 경우 포럼을 통해서 알려주세요.

속도 줄이기

애플리케이션에서 RateExceededError가 발생하면 속도를 줄여야 합니다. 속도를 줄이지 않으면 애플리케이션의 오류 복구 기능이 더 지연될 수 있습니다. 이 작업을 수행하는 가장 간단한 방법 중 하나는 다른 요청을 계속하거나 요청을 다시 시도할 때 RateExceededError.retryAfterSeconds 값을 인정하는 것입니다.

예를 들어 자바에서 다른 요청을 처리하기 전에 스레드를 일시 중지하는 가장 간단한 방법은 Thread.sleep()입니다.

try {
  ...
} catch (ApiException e) {
  for (ApiError error : e.getErrors()) {
    if (error instanceof RateExceededError) {
      RateExceededError rateExceeded = (RateExceededError) error;
      Thread.sleep(rateExceeded.getRetryAfterSeconds() * 1000);
    }
  }
  ...
}

단순하고 간단한 방법이지만 더 많은 전체 처리량을 달성하는 데는 차선책이므로 최후의 방법으로 사용되어야 합니다.

속도 제한을 초과할 가능성을 완화하는 방법에는 여러 가지가 있습니다. 메시지, 재전달 및 조절과 같은 엔터프라이즈 통합 패턴(EIP) 개념을 숙지하면 더 강력한 클라이언트 애플리케이션을 구축하는 데 도움이 됩니다.

다음 섹션에서 이러한 권장 사례를 살펴 보겠습니다. 완화 사례를 적용할 때에도 RateExceededError를 처리할 수 있어야 합니다.

관리

클라이언트 측에서 요청 개수를 적극적으로 감소시키고 QPS를 조절함으로써 애플리케이션을 제어하고 RateExceededError를 최대한 완화할 수 있습니다.

다음은 몇 가지 권장되는 방법으로, 가장 간단한 전략에서 강력하고 정교한 아키텍처 순서로 나열되어 있습니다.

  • 동시 스레드 제한
  • 일괄 처리 요청
  • MutateJobService 사용
  • 조절/속도 제한기
  • 다른 요청으로 인터리브 요청
  • 대기열
  • 새 계정과 기존 계정을 차별화

동시 스레드 제한

RateExceededError의 근본 원인을 찾으려는 경우, 클라이언트 애플리케이션에서 스레드를 과도하게 만들고 모든 스레드가 동시에 애드워즈 API를 호출하는 경우가 자주 발생합니다. 클라이언트 애플리케이션이 가질 수 있는 동시 스레드의 수에는 제한이 없지만, 무제한 개수의 스레드를 통해 요청을 동시에 보내면 개발자 토큰 수준에서 RPS(초당 요청) 제한을 쉽게 초과할 수 있습니다.

모든 프로세스와 시스템에서 요청을 만들려는 동시 스레드의 전체 개수에 대한 합리적인 상한선을 설정한 후 속도 제한을 초과하지 않으면서 처리량을 최적화하도록 상향 조정하는 것이 좋습니다.

또한 모든 스레드에서 클라이언트 측의 QPS를 조절하는 것을 고려할 수 있습니다(조절/속도 제한기 참조).

일괄 처리 요청

가능하면 여러 요청을 단일 요청으로 일괄 처리하는 것이 좋습니다. 일괄 처리 요청은 mutate 호출에 가장 적합합니다. 예를 들어 여러 개의 AdGroupAd 상태를 업데이트하는 경우, AdGroupAd별로 mutate를 매번 호출하는 대신 mutate를 한 번만 호출하고 여러 개의 AdGroupAdOperation을 한 번에 전달할 수 있습니다. 권장사항에서 추가 예제와 작업을 그룹화하는 최선의 방법을 참조하세요.

여러 작업을 단일 요청으로 결합할 때, 대부분의 요청이 단일 요청임을 유념해야 합니다. 작업이 실패할 경우 전체 요청이 실패하며 아무 것도 업데이트되지 않습니다. 부분 실패 기능을 활용하여 이러한 동작을 변경할 수 있습니다.

마지막으로 일괄 처리 요청은 전체 요청 수를 줄이고 분당 요청(RPM) 속도 제한을 완화하지만, 하나의 계정에서 많은 수의 작업을 수행하면 분당 작업(OPM) 속도 제한을 트리거할 수 있습니다.

MutateJobService 사용

오래 걸리는 작업, 많은 수의 작업 처리, 또는 여러 서비스에 많은 수의 작업이 있는 경우, MutateJobService를 활용하도록 고려해 보세요. MutateJobService를 사용한 일괄 처리에 대한 전체 가이드는 애드워즈 API 개발자 사이트에서 참조하세요. MutateJobService는 Google 클라우드 안에서 수천 개의 작업을 비동기적으로 예약하고 실행할 수 있습니다. 개발자는 작업이 완료되었는지 보기 위해 결과를 조사하기만 하면 됩니다.

조절/속도 제한기

클라이언트 애플리케이션에서 전체 스레드 수를 제한하면서 클라이언트 측에서 속도 제한기를 구현할 수도 있습니다. 이러한 전략은 모든 프로세스 또는 클러스터에 스레드가 모두 클라이언트 측의 특정 QPS 제한이 적용되도록 보장합니다.

예를 들어 Guava 속도 제한기를 확인하거나, 클러스터 환경에서 작동하는 고유의 토큰 버킷 기반 알고리즘을 구현할 수 있습니다. 예를 들어 토큰을 생성하여 데이터베이스와 같은 공유된 트랜잭션 저장소에 저장하면, 각 클라이언트는 요청을 처리하기 전에 토큰을 획득하여 사용해야 합니다. 토큰이 모두 사용되면 클라이언트는 다음 배치의 토큰이 생성될 때까지 기다려야 할 것입니다.

대부분의 경우 조절은 개발자 토큰 범위 내에서 속도 제한을 초과하지 않는 데 도움이 됩니다.

다른 계정으로 인터리브 요청

계정의 범위에서 속도 제한을 초과하는 경우 클라이언트 측에서 계정에 대해 QPS 속도 제한을 할 수 있습니다. 그러나 수천 개의 계정을 관리하는 경우 번거로운 작업이 될 수 있습니다. 다른 대안의 간단한 전략은 계정을 기반으로 요청을 인터리브하는 것입니다.

예를 들어 5,000개의 mutate 작업을 10개의 계정으로 수행하는 경우, 한 가지 방법은 일괄 처리 작업을 다음과 같이 순차적으로 계정 1, 계정 2, 계정 3에 보내는 것입니다.

  1. 계정 1에 대한 500개의 mutate 작업을 보내고 5000개 작업에 대해 10번 반복합니다.
  2. 계정 2에 대한 500개의 mutate 작업을 보내고 10번 반복합니다.
  3. … (모든 10개 계정에 대해 끝날 때까지 반복합니다.)

이 방법은 간단하지만 계정의 범위에서 분당 작업(OPM) 수에 대한 속도 제한을 초과할 수 있습니다.

계정을 인터리브하면 요청이 다음과 같이 보입니다.

  1. 계정 1에 대한 500개의 mutate 작업을 보냅니다.
  2. 계정 2에 대한 500개의 mutate 작업을 보냅니다.
  3. 계정 3에 대한 500개의 mutate 작업을 보냅니다.
  4. … (모든 10개 계정에 대해 끝날 때까지 반복합니다.)
  5. 계정 1에 대한 500개의 mutate 작업을 보냅니다.
  6. 계정 2에 대한 500개의 mutate 작업을 보냅니다.
  7. … (모든 계정에 대해 5,000개 작업을 모두 마칠 때까지 반복합니다.)

이 예제는 계정을 기반으로 요청을 인터리브하는 방법을 보여 줍니다. 또한 MutateJobService도 각자의 사용 사례에 맞는지 확인해보시기 바랍니다.

대기열

메시지 대기열은 작업 부하를 분산하고, 요청과 소비자 속도도 제어할 수 있는 사용 가능한 최적의 솔루션입니다. 사용 가능한 메시지 대기열 옵션(일부는 오픈소스이고 일부는 독점)에는 여러 가지가 있는데, 그 중 많은 대기열이 여러 언어에서 작동합니다.

메시지 대기열을 사용하는 경우 여러 생산자 메시지를 대기열에 밀어넣고, 여러 소비자가 해당 메시지를 처리할 수 있습니다. 소비자 측에서 동시 소비자 수를 제한하여 조절을 구현하거나, 생산자 또는 소비자 측에서 속도 제한기/조절기를 구현할 수 있습니다.

예를 들어 메시지 소비자가 RateExceededError를 받은 경우 소비자는 요청이 다시 시도되도록 대기열로 다시 배달할 수 있습니다. 동시에 소비자는 오류에서 복구하기 위해 모든 소비자에게 몇 초간 처리를 일시 중지하도록 알릴 수 있습니다.

새 계정 및 기존 계정에 대한 대기열 및 속도 제한 차별화

대기열이나 속도 제한기 전략을 구현할 때 새로 만든 애드워즈 계정이 기존 계정보다 훨씬 더 엄격한 속도 제한(즉, 낮은 QPS)을 가질 수 있습니다. 이를 통해 조직에서 지속적으로 새로운 계정을 만들고 관리할 많은 기존 계정이 있는 경우, 두 유형의 계정에 대해 서로 다른 속도 제한기나 조절기를 사용하는 것이 좋습니다.

이 방법을 사용하면, 낮은 QPS를 가진 계정에 의해 제한되지 않고 두 유형의 계정 모두에 대해 처리량을 최대화할 수 있습니다.

일반적으로 새로운 애드워즈 계정에 대한 더 엄격한 제한은 계정이 광고를 게시하기 시작하면 완화됩니다.

도움이 필요하세요?

오류 또는 API 관련 모든 질문은 언제든지 포럼에 게시하시기 바랍니다. 적극 지원해 드리겠습니다.

다음에 대한 의견 보내기...

도움이 필요하시나요? 지원 페이지를 방문하세요.