Menguji aplikasi secara lokal dengan emulator

Untuk mengembangkan dan menguji aplikasi secara lokal, Anda dapat menggunakan emulator Pub/Sub, yang menyediakan emulasi lokal layanan Pub/Sub produksi. Jalankan emulator Pub/Sub menggunakan Google Cloud CLI.

Untuk menjalankan aplikasi terhadap emulator, mulai emulator dan tetapkan variabel lingkungan terlebih dahulu. Aplikasi Anda harus berkomunikasi dengan emulator, bukan layanan Pub/Sub produksi. Resource yang dibuat dan pesan yang dipublikasikan ke emulator akan dipertahankan selama masa aktif sesi emulator.

Sebelum memulai

Lengkapi prasyarat berikut sebelum Anda menggunakan emulator Pub/Sub:

Menginstal emulator

Instal emulator dari command prompt:

gcloud components install pubsub-emulator
gcloud components update

Menginstal emulator sebagai image container

Untuk menginstal dan menjalankan emulator sebagai container, download dan instal image Docker gCloud.

Memulai emulator

Mulai emulator dengan memanggil pubsub start dari command prompt. Sebelum menjalankan perintah, ganti PUBSUB_PROJECT_ID dengan project ID Google Cloud yang valid. String ini tidak perlu mewakili project Google Cloud sungguhan karena emulator Pub/Sub berjalan secara lokal.

gcloud beta emulators pubsub start --project=PUBSUB_PROJECT_ID [options]

Lihat gcloud beta emulators pubsub start untuk mengetahui daftar lengkap flag.

Setelah memulai emulator, Anda akan melihat pesan yang terlihat seperti berikut:

...
[pubsub] This is the Pub/Sub fake.
[pubsub] Implementation may be incomplete or differ from the real system.
...
[pubsub] INFO: Server started, listening on 8085

Pesan ini menunjukkan bahwa server Pub/Sub berjalan di endpoint emulator di mesin lokal Anda, bukan endpoint Google Cloud. Semua operasi terjadi secara lokal, termasuk operasi berikut:

  • Membuat topik atau langganan
  • Penerbitan
  • Berlangganan

Menyetel variabel lingkungan

Setelah memulai emulator, Anda harus menetapkan variabel lingkungan agar aplikasi Anda terhubung ke emulator, bukan Pub/Sub. Tetapkan variabel lingkungan ini pada mesin yang sama dengan yang digunakan untuk menjalankan aplikasi Anda.

Anda harus menetapkan variabel lingkungan setiap kali memulai emulator. Variabel lingkungan bergantung pada nomor port yang ditetapkan secara dinamis, yang dapat berubah saat Anda memulai ulang emulator.

Menetapkan variabel secara otomatis

Jika aplikasi dan emulator berjalan pada mesin yang sama, Anda dapat menetapkan variabel lingkungan secara otomatis:

Linux / Mac

Jalankan env-init menggunakan substitusi perintah:

$(gcloud beta emulators pubsub env-init)

Windows

Buat dan jalankan file batch menggunakan output dari env-init:

gcloud beta emulators pubsub env-init > set_vars.cmd && set_vars.cmd

Sekarang aplikasi akan terhubung ke emulator Pub/Sub.

Menetapkan variabel secara manual

Jika aplikasi dan emulator Anda berjalan pada mesin yang berbeda, tetapkan variabel lingkungan secara manual:

  1. Jalankan perintah env-init:

     gcloud beta emulators pubsub env-init

  2. Pada mesin yang menjalankan aplikasi Anda, tetapkan nilai dan variabel lingkungan PUBSUB_EMULATOR_HOST seperti yang diarahkan oleh output perintah env-init. Konfigurasi ini menghubungkan aplikasi Anda ke emulator. Anda dapat memilih untuk menetapkan variabel lingkungan PUBSUB_PROJECT_ID untuk project yang ingin digunakan untuk emulator. Contoh:

    Linux / macOS
    export PUBSUB_EMULATOR_HOST=[::1]:8432
    export PUBSUB_PROJECT_ID=my-project-id
    Windows
    set PUBSUB_EMULATOR_HOST=[::1]:8432
    set PUBSUB_PROJECT_ID=my-project-id

Sekarang aplikasi akan terhubung ke emulator Pub/Sub.

Catatan: Jika menggunakan server pengembangan lokal Python App Engine Standar, Anda harus meneruskan variabel lingkungan ini pada command line sebagai berikut:

dev_appserver.py app.yaml --env_var PUBSUB_EMULATOR_HOST=${PUBSUB_EMULATOR_HOST}

dev_appserver.py disertakan dalam [PATH_TO_CLOUD_SDK]/google-cloud-sdk/bin/dev_appserver.py Anda.

Menggunakan emulator

Untuk menggunakan emulator, Anda harus memiliki aplikasi yang dibangun menggunakan Library Klien Cloud. Emulator tidak mendukung Google Cloud Console atau perintah gcloud pubsub.

Contoh berikut menunjukkan penggunaan emulator dan aplikasi yang menggunakan Library Klien Python Cloud untuk menjalankan berbagai operasi. Contoh operasi ini mencakup cara membuat topik, memublikasikan pesan, dan membaca pesan.

Selesaikan langkah-langkah berikut di mesin tempat Anda menetapkan variabel lingkungan emulator:

  1. Dapatkan sampel Pub/Sub Python dari GitHub dengan meng-clone repositori Python penuh.

  2. Di repositori yang di-clone, buka direktori samples/snippets. Anda menyelesaikan sisa langkah-langkah tersebut dalam direktori ini.

  3. Dari dalam direktori samples/snippets, instal dependensi yang diperlukan untuk menjalankan contoh:

    pip install -r requirements.txt
    
  4. Membuat topik:

     python publisher.py PUBSUB_PROJECT_ID create TOPIC_ID
    
  5. (Opsional) Jika Anda tidak memiliki endpoint push lokal untuk menguji langganan push di emulator, selesaikan langkah-langkah berikut untuk membuatnya di http://[::1]:3000/messages.

    1. Instal Server JSON.
      npm install -g json-server
      
    2. Mulai Server JSON.
      json-server --port 3000 --watch db.json
      
      dengan db.json berisi kode awal berikut:
      {
         "messages": []
      }
      
    3. Catat http://[::1]:3000/messages untuk PUSH_ENDPOINT di langkah berikutnya.
  6. Buat langganan ke topik:

    • Membuat langganan pull:

      python subscriber.py PUBSUB_PROJECT_ID create TOPIC_ID SUBSCRIPTION_ID
      
    • Buat langganan push:

      python subscriber.py PUBSUB_PROJECT_ID create-push TOPIC_ID SUBSCRIPTION_ID \
      PUSH_ENDPOINT
      
  7. Memublikasikan pesan ke topik:

     python publisher.py PUBSUB_PROJECT_ID publish TOPIC_ID
    
  8. Baca pesan yang dipublikasikan ke topik:

    • Mengambil pesan dari langganan pull Anda:

      python subscriber.py PUBSUB_PROJECT_ID receive SUBSCRIPTION_ID
      
    • Amati pesan yang dikirim ke endpoint push lokal Anda. Misalnya, pesan akan terlihat seperti berikut:

      {
        "messages": [
            {
                "subscription": "projects/PUBSUB_PROJECT_ID/subscriptions/SUBSCRIPTION_ID",
                "message": {
                    "data": "TWVzc2FnZSBudW1iZXIgMQ==",
                    "messageId": "10",
                    "attributes": {}
                },
                "id": 1
            },
            ...
        ]
      }
      

Mengakses variabel lingkungan

Di semua bahasa kecuali Java dan C#, jika Anda telah menetapkan PUBSUB_EMULATOR_HOST seperti yang dijelaskan dalam Menetapkan variabel lingkungan, library klien Pub/Sub akan otomatis memanggil API yang berjalan di instance lokal, bukan Pub/Sub.

Namun, library klien C# dan Java mengharuskan Anda mengubah kode agar dapat menggunakan emulator:

C#

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan C# di panduan memulai Pub/Sub menggunakan library klien. Untuk informasi selengkapnya, lihat dokumentasi referensi API C# Pub/Sub.

Untuk melakukan autentikasi ke Pub/Sub, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.


using Google.Api.Gax;
using Google.Cloud.PubSub.V1;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

public class EmulatorSupportSample
{
    public async Task WithEmulatorAsync(string projectId, string topicId, string subscriptionId)
    {
        // Use EmulatorDetection.EmulatorOrProduction to create service clients that will
        // that will connect to the PubSub emulator if the PUBSUB_EMULATOR_HOST environment
        // variable is set, but will otherwise connect to the production environment.

        // Create the PublisherServiceApiClient using the PublisherServiceApiClientBuilder
        // and setting the EmulatorDection property.
        PublisherServiceApiClient publisherService = await new PublisherServiceApiClientBuilder
        {
            EmulatorDetection = EmulatorDetection.EmulatorOrProduction
        }.BuildAsync();

        // Use the client as you'd normally do, to create a topic in this example.
        TopicName topicName = new TopicName(projectId, topicId);
        publisherService.CreateTopic(topicName);

        // Create the SubscriberServiceApiClient using the SubscriberServiceApiClientBuilder
        // and setting the EmulatorDection property.
        SubscriberServiceApiClient subscriberService = await new SubscriberServiceApiClientBuilder
        {
            EmulatorDetection = EmulatorDetection.EmulatorOrProduction
        }.BuildAsync();

        // Use the client as you'd normally do, to create a subscription in this example.
        SubscriptionName subscriptionName = new SubscriptionName(projectId, subscriptionId);
        subscriberService.CreateSubscription(subscriptionName, topicName, pushConfig: null, ackDeadlineSeconds: 60);

        // Create the PublisherClient using PublisherClientBuilder to set the EmulatorDetection property.
        PublisherClient publisher = await new PublisherClientBuilder
        {
            TopicName = topicName,
            EmulatorDetection = EmulatorDetection.EmulatorOrProduction
        }.BuildAsync();
        // Use the client as you'd normally do, to send a message in this example.
        await publisher.PublishAsync("Hello, Pubsub");
        await publisher.ShutdownAsync(TimeSpan.FromSeconds(15));

        // Create the SubscriberClient using SubscriberClientBuild to set the EmulatorDetection property.
        SubscriberClient subscriber = await new SubscriberClientBuilder
        {
            SubscriptionName = subscriptionName,
            EmulatorDetection = EmulatorDetection.EmulatorOrProduction
        }.BuildAsync();
        List<PubsubMessage> receivedMessages = new List<PubsubMessage>();

        // Use the client as you'd normally do, to listen for messages in this example.
        await subscriber.StartAsync((msg, cancellationToken) =>
        {
            receivedMessages.Add(msg);
            Console.WriteLine($"Received message {msg.MessageId} published at {msg.PublishTime.ToDateTime()}");
            Console.WriteLine($"Text: '{msg.Data.ToStringUtf8()}'");
            // In this example we stop the subscriber when the message is received.
            // You may leave the subscriber running, and it will continue to received published messages
            // if any.
            // This is non-blocking, and the returned Task may be awaited.
            subscriber.StopAsync(TimeSpan.FromSeconds(15));
            // Return Reply.Ack to indicate this message has been handled.
            return Task.FromResult(SubscriberClient.Reply.Ack);
        });
    }
}

Java

Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Java di panduan memulai Pub/Sub menggunakan library klien. Untuk informasi selengkapnya, lihat dokumentasi referensi API Java Pub/Sub.

Untuk melakukan autentikasi ke Pub/Sub, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, baca Menyiapkan autentikasi untuk lingkungan pengembangan lokal.

String hostport = System.getenv("PUBSUB_EMULATOR_HOST");
ManagedChannel channel = ManagedChannelBuilder.forTarget(hostport).usePlaintext().build();
try {
  TransportChannelProvider channelProvider =
      FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel));
  CredentialsProvider credentialsProvider = NoCredentialsProvider.create();

  // Set the channel and credentials provider when creating a `TopicAdminClient`.
  // Similarly for SubscriptionAdminClient
  TopicAdminClient topicClient =
      TopicAdminClient.create(
          TopicAdminSettings.newBuilder()
              .setTransportChannelProvider(channelProvider)
              .setCredentialsProvider(credentialsProvider)
              .build());

  TopicName topicName = TopicName.of("my-project-id", "my-topic-id");
  // Set the channel and credentials provider when creating a `Publisher`.
  // Similarly for Subscriber
  Publisher publisher =
      Publisher.newBuilder(topicName)
          .setChannelProvider(channelProvider)
          .setCredentialsProvider(credentialsProvider)
          .build();
} finally {
  channel.shutdown();
}

Menghentikan emulator

Untuk menghentikan emulator, tekan Control+C.

Setelah menghentikan emulator, jalankan perintah berikut untuk menghapus variabel lingkungan PUBSUB_EMULATOR_HOST sehingga aplikasi Anda akan terhubung ke Pub/Sub:

Linux / macOS
unset PUBSUB_EMULATOR_HOST
Windows
set PUBSUB_EMULATOR_HOST=

Argumen command line emulator

Untuk mengetahui detail tentang argumen command line untuk emulator Pub/Sub, lihat gcloud beta emulators pubsub.

Fitur yang didukung

Emulator mendukung fitur Pub/Sub berikut:

  • Memublikasikan pesan
  • Menerima pesan dari langganan push dan pull
  • Mengurutkan pesan
  • Memutar ulang pesan
  • Meneruskan pesan ke topik yang dihentikan pengirimannya
  • Coba lagi kebijakan terkait pengiriman pesan
  • Dukungan skema untuk Avro

Batasan umum

  • RPC UpdateTopic dan UpdateSnapshot tidak didukung.
  • Operasi IAM tidak didukung.
  • Retensi pesan yang dapat dikonfigurasi tidak didukung; semua pesan dipertahankan tanpa batas waktu.
  • Akhir masa berlaku langganan tidak didukung. Langganan tidak akan habis masa berlakunya.
  • Pemfilteran tidak didukung.
  • Dukungan skema untuk buffering protokol.
  • Langganan BigQuery dapat dibuat, tetapi tidak mengirim pesan ke BigQuery.
  • Mencari ke stempel waktu untuk langganan yang dipesan tidak didukung.

Untuk melaporkan masalah, kirimkan Issue tracker publik.

Langkah selanjutnya

  • Untuk mempelajari cara menggunakan emulator Pub/Sub dengan minikube, lihat postingan blog ini.