本指南概述了如何自定义 Java 客户端库的几个更高级的方面。一个常见模式是,许多此类功能依赖于底层 Callable 而不是标准便捷方法。可调用对象通常是查找此处未记录的其他每 RPC 功能的好去处。
超时
Java 库提供了一个界面,用于在每次调用时设置超时时间。
默认值根据 googleads_grpc_service_config.json 中的 method_config/timeout 设置来设置。如果您需要强制缩短 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.
}
}
您可以将超时时间设置为 2 小时或更长时间,但 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()(或特定于版本的访问器,例如 getVersion25())都会创建新的底层连接和关联资源。
请确保在不再需要服务客户端时将其关闭。您可以在 try-with-resources 块中或通过对服务客户端调用 close() 来执行此操作。
如果您尝试使用已关闭的服务客户端发出 API 请求,服务客户端方法会抛出 java.util.concurrent.RejectedExecutionException。
如果 JAR 大于 32 MB,App Engine 部署会失败
App Engine 为每个上传的文件设置了 32 MB 的配额。google-ads 的 JAR 要大得多,尤其是在使用 shade 或 shadow JAR 部署时。如果您手动部署 JAR,可能会遇到如下错误:
ERROR: (gcloud.app.deploy) Cannot upload file [<your-app>/WEB-INF/lib/google-ads-46.1.0.jar],
which has size [66095767] (greater than maximum allowed size of [33554432])
请改为使用 App Engine Gradle 插件或 Maven 插件进行部署。每个插件都提供一个 enableJarSplitting 选项,用于将每个 JAR 拆分成 10 MB 的块,然后上传这些块。
影子依赖项
如果您的项目具有与库的依赖项相冲突的依赖项,请使用以下命令之一检查项目的依赖项层次结构,然后根据需要修改项目的依赖项(或使用物料清单):
Maven
mvn dependency:treeGradle
./gradlew dependencies如果无法解决依赖项冲突,您可以改为依赖库的 shaded 版本:
Maven
<dependency> <groupId>com.google.api-ads</groupId> <artifactId>google-ads-shadowjar</artifactId> <version>46.1.0</version> </dependency>
Gradle
implementation 'com.google.api-ads:google-ads-shadowjar:46.1.0'