الاستخدام المتقدّم

يوضّح هذا الدليل كيفية تخصيص العديد من الجوانب الأكثر تقدّمًا في مكتبة برامج Java. من الأنماط الشائعة أنّ العديد من هذه الميزات تعتمد على Callable الأساسي بدلاً من الطرق العادية المريحة. يُعدّ العنصر القابل للاستدعاء بشكل عام مكانًا جيدًا للبحث عن ميزات أخرى لكل طلب RPC غير موضّحة هنا.

عملية استبعاد للقناة لمهلة معيّنة

توفّر مكتبة Java واجهة لضبط مهلات على مستوى كل طلب. يتم ضبط القيمة التلقائية استنادًا إلى إعداد method_config/timeout في googleads_grpc_service_config.json. اضبط قيمة أقل إذا كنت بحاجة إلى فرض حدّ أقصى أقصر للوقت المسموح به لطلب بيانات من واجهة برمجة التطبيقات.

لاستخدام هذه الميزة، يمكنك استدعاء العنصر 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.
  }
}

يمكنك ضبط المهلة على ساعتَين أو أكثر، ولكن قد تستمر واجهة برمجة التطبيقات في إنهاء مهلة الطلبات التي تستغرق وقتًا طويلاً جدًا وتعرض الخطأ 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())، والتي تحمّل فئات خدمة واجهة برمجة التطبيقات في وقت واحد لتوفير آلية ملائمة لإنشاء عملاء الخدمة.

إذا كان أداء الطلب الأول يقع ضمن المسار الحرج لتطبيقك، اتّبِع الخطوات التالية:

  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 (ApiException ex) {
          // Do nothing, we're expecting this to fail.
        }
      }
    }
    

يجب تشغيل طلبات الإحماء مرة واحدة فقط لكل عملية. ويؤدي كل إنشاء لاحق لعميل الخدمة إلى إعادة استخدام الفئات المُحمَّلة مسبقًا تلقائيًا.

إعادة استخدام عميل الخدمة

يجب إعادة استخدام نُسخ عميل الخدمة حيثما كان ذلك عمليًا لأنّ كل طلب إلى GoogleAdsClient.getLatestVersion().createYYYServiceClient() (أو طريقة وصول خاصة بالإصدار مثل getVersion26()) ينشئ اتصالاً أساسيًا جديدًا وموارد مرتبطة به.

تأكَّد من إغلاق عميل الخدمة عندما لا تكون هناك حاجة إليه. يمكنك إجراء ذلك في مجموعة try-with-resources أو من خلال استدعاء close() على عميل الخدمة.

إذا حاولت استخدام عميل خدمة مغلق لطلب بيانات من واجهة برمجة التطبيقات، ستعرض طريقة عميل الخدمة الخطأ java.util.concurrent.RejectedExecutionException.

يتعذّر نشر App Engine إذا كان حجم ملف JAR أكبر من 32 ميغابايت

يبلغ الحد الأقصى المسموح به في App Engine‏ 32 ميغابايت لكل ملف يتم تحميله. إنّ ملف JAR لـ google-ads أكبر بكثير من هذا، خاصةً عند استخدام عمليات نشر 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])

بدلاً من ذلك، يمكنك النشر باستخدام مكوّن Gradle الإضافي أو مكوّن Maven الإضافي في App Engine. يوفّر كل مكوّن إضافي خيار enableJarSplitting الذي يقسّم كل ملف JAR إلى أجزاء بحجم 10 ميغابايت ويحمّلها بدلاً من ذلك.

المهام التابعة المخفية

إذا كان مشروعك يتضمّن تبعيات تتعارض مع تبعيات المكتبة، يمكنك فحص التسلسل الهرمي لتبعيات مشروعك باستخدام أحد الأوامر التالية، ثم تعديل تبعيات مشروعك حسب الحاجة (أو استخدام قائمة المواد):

Maven

mvn dependency:tree

Gradle

./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'