В этом руководстве рассказывается, как настроить некоторые расширенные аспекты клиентской библиотеки Java. Многие из этих функций основаны на базовом Callable, а не на стандартных методах. В вызываемом объекте можно найти другие функции для каждого RPC, которые не описаны в этой статье.
Время ожидания
Библиотека 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.1.0.jar],
which has size [66095767] (greater than maximum allowed size of [33554432])
Вместо этого используйте плагин App Engine Gradle или Maven. В каждом плагине есть параметр enableJarSplitting, который разбивает JAR-файлы на части по 10 МБ и загружает их.
Теневые зависимости
Если в вашем проекте есть зависимости, которые конфликтуют с зависимостями библиотеки, проверьте иерархию зависимостей проекта с помощью одной из следующих команд, а затем измените зависимости проекта нужным образом (или используйте спецификацию):
Maven
mvn dependency:treeGradle
./gradlew dependenciesЕсли устранить конфликты зависимостей невозможно, вы можете использовать затененную версию библиотеки:
Maven
<dependency> <groupId>com.google.api-ads</groupId> <artifactId>google-ads-shadowjar</artifactId> <version>48.1.0</version> </dependency>
Gradle
implementation 'com.google.api-ads:google-ads-shadowjar:48.1.0'