שימוש מתקדם

במדריך הזה מוסבר איך להתאים אישית כמה מההיבטים המתקדמים יותר של ספריית הלקוח של Java. דפוס נפוץ הוא שרבות מהתכונות האלה מסתמכות על Callable הבסיסי ולא על השיטות הרגילות. בדרך כלל, הפונקציה שאפשר לקרוא לה היא מקום טוב לחפש בו תכונות אחרות לכל RPC שלא מתועדות כאן.

חסימה זמנית

ספריית Java מספקת ממשק להגדרת פסק זמן ברמת כל קריאה. ערך ברירת המחדל מוגדר על סמך ההגדרה method_config/timeout בקובץ googleads_grpc_service_config.json. אם אתם רוצים להגביל את הזמן המקסימלי של קריאה ל-API, אתם יכולים להגדיר ערך נמוך יותר.

כדי להשתמש בתכונה הזו, צריך להשתמש ישירות באובייקט שאפשר להפעיל. לדוגמה, אם מתקשרים אל GoogleAdsService.searchStream(), פסק הזמן יוגדר כך:

try (GoogleAdsServiceClient googleAdsServiceClient =
    googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) {
  // Constructs the SearchGoogleAdsStreamRequest.
  SearchGoogleAdsStreamRequest request = ...

  // Executes the API call, with a timeout of 5 minutes.
  ServerStream<SearchGoogleAdsStreamResponse> result = googleAdsServiceClient
      .searchStreamCallable()
      .call(request,
          GrpcCallContext.createDefault().withTimeout(Duration.of(5, ChronoUnit.MINUTES)));
}

אפשר להגדיר את הזמן הקצוב לתפוגה לשעתיים או יותר, אבל יכול להיות שעדיין יחול פסק זמן על בקשות ל-API שפועלות במשך זמן רב מאוד, ותוחזר שגיאה DEADLINE_EXCEEDED. אם הבעיה הזו מתרחשת, בדרך כלל הכי טוב לפצל את השאילתה ולהריץ את המקטעים במקביל. כך נמנע מצב שבו בקשה שפועלת במשך זמן רב נכשלת, והדרך היחידה לשחזר אותה היא להפעיל אותה מחדש מההתחלה.

ניסיון חוזר להגדרות

ספריית Java מספקת גם ממשק להגדרת הגדרות ניסיון חוזר ברמת כל קריאה. כדי להשתמש בתכונה הזו, צריך להשתמש ישירות באובייקט שאפשר להפעיל. לדוגמה, אם מתקשרים אל GoogleAdsService.searchStream(), הגדרות הניסיון החוזר יוגדרו באופן הבא:

// 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());

// Creates and issues a search Google Ads stream request.
ServerStream<SearchGoogleAdsStreamResponse> stream =
    googleAdsServiceClient.searchStreamCallable().call(request, context);

אופטימיזציה של ביצועי זמן ההפעלה

יכול להיות שתבחינו בעיכוב קל בפעם הראשונה שמופעלת דוגמה של GoogleAdsClient. הסיבה לכך היא הממשק הדינמי לשירותים (GoogleAdsClient.getVersionXX()), שבו כל מחלקות ה-API נטענות בבת אחת כדי לספק מנגנון נוח יותר ליצירת מחלקות שירות.

אם הביצועים של הבקשה הראשונה נמצאים בנתיב הקריטי של האפליקציה, צריך לבצע את השלבים הבאים:

  1. יוצרים את GoogleAdsClient בהפעלה, לפני שמגישים בקשות משתמשים.

  2. כשמתחילים את התהליך, שולחים כמה בקשות חימום ל-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 (GoogleAdsException ex) {
          // Do nothing, we're expecting this to fail.
        }
      }
    }
    

צריך להריץ את בקשות החימום רק פעם אחת לכל תהליך. כל יצירה של לקוח שירות לאחר מכן תשתמש מחדש באופן אוטומטי במחלקות שנטענו מראש.

שימוש חוזר בלקוח שירות

מומלץ לעשות שימוש חוזר במופעים של לקוחות שירותים כשזה אפשרי, כי כל קריאה ל-GoogleAdsClient.getVersionXXX().createYYYServiceClient() תיצור חיבור TCP חדש.

חשוב לוודא שסוגרים את הלקוח כשכבר לא צריך אותו. אפשר לעשות את זה בבלוק try-with-resources או באמצעות קריאה ל-close() בלקוח השירות.

אם תנסו להשתמש בלקוח שירות סגור כדי לשלוח בקשות API, שיטת לקוח השירות תזרוק java.util.concurrent.RejectedExecutionException.

פריסה של App Engine נכשלת אם קובץ ה-JAR גדול מ-32MB

ב-App Engine, כל קובץ שמעלים יכול להיות בגודל של עד 32MB. קובץ ה-JAR של google-ads יהיה גדול בהרבה, במיוחד אם משתמשים בפריסות של shade/shadow jar. אם אתם פורסים קובצי JAR באופן ידני, יכול להיות שתקבלו שגיאות כמו:

ERROR: (gcloud.app.deploy) Cannot upload file [<your-app>/WEB-INF/lib/google-ads-39.0.0.jar],
which has size [66095767] (greater than maximum allowed size of [33554432])

במקום זאת, אפשר לפרוס באמצעות התוסף Gradle או התוסף Maven של AppEngine. לכל אחת מהאפשרויות יש אפשרות enableJarSplitting שתפצל כל קובץ JAR לחלקים של 10MB ותעלה אותם במקום זאת.

יחסי תלות של צללים

אם בפרויקט יש יחסי תלות שמתנגשים עם הספרייה, צריך לבדוק את יחסי התלות של הפרויקט באמצעות אחת מהפקודות הבאות, ואז לשנות את יחסי התלות של הפרויקט לפי הצורך.

Maven

mvn dependency:tree

Gradle

./gradlew dependencies

אם אי אפשר לפתור את הבעיות שנובעות מתלות, אפשר להסתמך על הגרסה המוצללת של הספרייה.

Maven

<dependency>
  <groupId>com.google.api-ads</groupId>
  <artifactId>google-ads-shadowjar</artifactId>
  <version>39.0.0</version>
</dependency>

Gradle

implementation 'com.google.api-ads:google-ads-shadowjar:39.0.0'