В этом руководстве рассказывается, как настроить некоторые расширенные аспекты клиентской библиотеки Java. Многие из этих функций основаны на базовом Callable, а не на стандартных методах. В вызываемом объекте можно найти другие функции, которые не описаны в этой статье.
Время ожидания
Библиотека Java позволяет задавать тайм-ауты на уровне отдельных вызовов.
Значение по умолчанию задается на основе настройки method_config/timeout в googleads_grpc_service_config.json. Установите меньшее значение, если вам нужно ограничить максимальное время вызова API.
Чтобы использовать эту функцию, вызовите объект Callable напрямую. Например, при вызове GoogleAdsService.searchStream() задайте время ожидания следующим образом:
try (GoogleAdsServiceClient googleAdsServiceClient =
googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) {
// Constructs the SearchGoogleAdsStreamRequest.
SearchGoogleAdsStreamRequest request =
SearchGoogleAdsStreamRequest.newBuilder()
.setCustomerId(Long.toString(customerId))
.setQuery("SELECT campaign.id, campaign.name FROM campaign")
.build();
// Executes the API call with a timeout of 5 minutes.
ServerStream<SearchGoogleAdsStreamResponse> stream =
googleAdsServiceClient
.searchStreamCallable()
.call(
request,
GrpcCallContext.createDefault()
.withTimeout(Duration.of(5, ChronoUnit.MINUTES)));
for (SearchGoogleAdsStreamResponse response : stream) {
// Processes the response rows.
}
}
Вы можете установить время ожидания, равное двум часам или более, но API все равно может прерывать выполнение слишком долгих запросов и возвращать ошибку DEADLINE_EXCEEDED.
Если это становится проблемой, обычно лучше всего разделить запрос и выполнить его части параллельно. Это позволяет избежать ситуации, когда длительный запрос завершается ошибкой и единственный способ восстановить его – запустить запрос заново с самого начала.
Настройки повторных попыток
Библиотека Java также предоставляет возможность настраивать повторные попытки на уровне вызова. Чтобы использовать эту функцию, вызовите объект Callable напрямую. Например, при вызове GoogleAdsService.searchStream() настройте повторные попытки следующим образом:
try (GoogleAdsServiceClient googleAdsServiceClient =
googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) {
SearchGoogleAdsStreamRequest request =
SearchGoogleAdsStreamRequest.newBuilder()
.setCustomerId(Long.toString(customerId))
.setQuery("SELECT campaign.id, campaign.name FROM campaign")
.build();
// Creates a context object with the custom retry settings.
GrpcCallContext context =
GrpcCallContext.createDefault()
.withRetrySettings(
RetrySettings.newBuilder()
.setInitialRetryDelay(Duration.ofMillis(10L))
.setMaxRetryDelay(Duration.ofSeconds(10L))
.setRetryDelayMultiplier(1.4)
.setMaxAttempts(10)
.setLogicalTimeout(Duration.ofSeconds(30L))
.build());
// Issues the streaming search request.
ServerStream<SearchGoogleAdsStreamResponse> stream =
googleAdsServiceClient.searchStreamCallable().call(request, context);
for (SearchGoogleAdsStreamResponse response : stream) {
// Processes the response rows.
}
}
Оптимизация времени запуска
При первом создании экземпляра GoogleAdsClient может возникнуть небольшая задержка. Это связано с удобным интерфейсом для сервисов (GoogleAdsClient.getLatestVersion()), который загружает классы сервисов API одновременно, чтобы упростить создание клиентов сервисов.
Если производительность первого запроса критически важна для вашего приложения, выполните следующие действия:
Создайте
GoogleAdsClientпри запуске, прежде чем обрабатывать запросы пользователей.Отправьте несколько тестовых запросов к Google Ads API в начале процесса. Пример:
// Runs some warm-up requests. try (GoogleAdsServiceClient googleAdsServiceClient = googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) { // Runs 5 warm-up requests. In our profiling we see that 90% of // performance loss is only experienced on the first API call. After 3 // subsequent calls we saw a negligible improvement in performance. for (int i = 0; i < 5; ++i) { // Warm-up queries are run with a nonexistent CID so the calls will // fail. If you have a CID that you know will be accessible with the // OAuth credentials provided you may want to provide that instead and // avoid the try-catch. try { googleAdsServiceClient.search("-1", "Warm-up query"); } catch (ApiException ex) { // Do nothing, we're expecting this to fail. } } }
Запросы на разогрев нужно выполнять только один раз для каждого процесса. При каждом последующем создании клиента сервиса автоматически используются предварительно загруженные классы.
Повторное использование клиентского сервиса
По возможности используйте повторно экземпляры клиентского сервиса, поскольку каждый вызов GoogleAdsClient.getLatestVersion().createYYYServiceClient() (или версии-специфического метода доступа, например getVersion26()) создает новое базовое подключение и связанные с ним ресурсы.
Обязательно закрывайте клиент сервиса, когда он больше не нужен. Это можно сделать в блоке try-with-resources или вызвав close() в клиенте сервиса.
Если вы попытаетесь использовать закрытый клиент сервиса для отправки запросов к API, метод клиента сервиса выдаст ошибку java.util.concurrent.RejectedExecutionException.
Не удается развернуть App Engine, если размер JAR-файла превышает 32 МБ
В App Engine действует квота на размер загружаемых файлов – 32 МБ. JAR-файл для google-ads значительно больше, особенно при использовании развертываний shade или shadow JAR. Если вы развертываете JAR-файлы вручную, могут возникать следующие ошибки:
ERROR: (gcloud.app.deploy) Cannot upload file [<your-app>/WEB-INF/lib/google-ads-48.0.0.jar],
which has size [66095767] (greater than maximum allowed size of [33554432])
Вместо этого используйте плагин Gradle или плагин Maven для App Engine. В каждом плагине есть параметр enableJarSplitting, который разбивает каждый JAR-файл на фрагменты по 10 МБ и загружает их.
Зависимости в тени
Если зависимости вашего проекта конфликтуют с зависимостями библиотеки, проверьте иерархию зависимостей проекта с помощью одной из следующих команд, а затем измените зависимости проекта (или используйте спецификацию BoM):
Maven
mvn dependency:treeGradle
./gradlew dependenciesЕсли устранить конфликты зависимостей невозможно, вы можете использовать затененную версию библиотеки:
Maven
<dependency> <groupId>com.google.api-ads</groupId> <artifactId>google-ads-shadowjar</artifactId> <version>48.0.0</version> </dependency>
Gradle
implementation 'com.google.api-ads:google-ads-shadowjar:48.0.0'