Menggunakan WebSocket

Halaman ini memberikan panduan dan praktik terbaik untuk menjalankan WebSocket atau layanan streaming lainnya di Cloud Run dan menulis klien untuk layanan tersebut.

Aplikasi WebSocket didukung di Cloud Run tanpa memerlukan konfigurasi tambahan. Namun, streaming WebSockets adalah permintaan HTTP yang masih tunduk pada waktu tunggu permintaan yang dikonfigurasi untuk layanan Cloud Run Anda, jadi Anda perlu memastikan setelan ini berfungsi dengan baik selama penggunaan WebSocket seperti menerapkan koneksi kembali di klien Anda.

Meskipun Anda menggunakan afinitas sesi di Cloud Run, yang memberikan afinitas upaya terbaik, permintaan WebSocket masih dapat berpotensi berakhir di instance yang berbeda, karena load balancing bawaan singkat ini. Untuk mengatasi masalah ini, Anda perlu menyinkronkan data antar-instance.

Perhatikan bahwa WebSocket di Cloud Run juga didukung jika Anda menggunakan Cloud Load Balancing.

Men-deploy contoh layanan WebSockets

Menggunakan Cloud Shell untuk men-deploy contoh layanan papan tulis yang menggunakan WebSockets dengan Cloud Run dengan cepat: Men-deploy sampel

Atau, jika Anda ingin men-deploy contoh layanan papan tulis tersebut secara manual:

  1. Clone repositori Socket.IO secara lokal menggunakan alat command line git:

    git clone https://github.com/socketio/socket.io.git
    
  2. Buka direktori contoh:

    cd socket.io/examples/whiteboard/
    
  3. Deploy layanan Cloud Run baru dengan membangun layanan dari kode sumber menggunakan Google Cloud CLI:

    gcloud run deploy whiteboard --allow-unauthenticated --source=.
    
  4. Setelah layanan di-deploy, buka dua tab browser terpisah lalu buka URL layanan. Apa pun yang Anda gambar dalam satu tab harus diterapkan ke tab lainnya (dan sebaliknya) karena klien terhubung ke instance yang sama melalui WebSockets.

Contoh tutorial lengkap chat WebSocket

Jika Anda menginginkan panduan kode lengkap, contoh kode tambahan tersedia di topik Tutorial Membuat layanan WebSocket Chat untuk Cloud Run.

Praktik Terbaik

Bagian tersulit dalam membuat layanan WebSockets di Cloud Run adalah menyinkronkan data di antara beberapa Cloud Run. Hal ini sulit dilakukan karena sifatnya yang Autoscaling dan stateless, serta karena adanya batas untuk konkurensi dan waktu tunggu permintaan.

Menangani waktu tunggu permintaan dan menghubungkan kembali klien

Permintaan WebSocket diperlakukan sebagai permintaan HTTP yang berjalan lama di Cloud Run. Waktu tunggu permintaan bergantung pada waktu tunggu permintaan (saat ini hingga 60 menit dan defaultnya hingga 5 menit) meskipun server aplikasi Anda tidak menerapkan waktu tunggu.

Oleh karena itu, jika klien membiarkan koneksi tetap terbuka lebih lama daripada waktu tunggu yang diperlukan untuk mengonfigurasi layanan Cloud Run, koneksi klien akan terputus ketika waktu permintaan habis.

Sehingga, WebSockets klien yang terhubung ke Cloud Run harus menangani koneksi kembali ke server jika waktu permintaan habis atau server terputus. Anda dapat melakukannya pada klien berbasis browser dengan menggunakan library seperti reconnecting-websocket atau dengan menangani "disconnect" jika Anda menggunakan librarySocketIO.

Penagihan yang dikenakan saat menggunakan WebSocket

Instance Cloud Run yang memiliki semua koneksi WebSocket terbuka akan dianggap aktif, sehingga CPU dialokasikan dan ditagih.

Memaksimalkan konkurensi

Layanan WebSocket biasanya didesain untuk menangani banyak koneksi secara bersamaan. Karena Cloud Run mendukung koneksi serentak (hingga 1000 per container), Google merekomendasikan agar Anda meningkatkan setelan serentak maksimum untuk container Anda agar nilainya lebih tinggi daripada default jika layanan Anda mampu menangani beban dengan resource yang diberikan.

Tentang sesi persisten (afinitas sesi)

Karena koneksi WebSocket bersifat stateful, klien akan tetap terhubung ke container yang sama di Cloud Run selama masa aktif koneksi. Hal ini secara alami menawarkan sesi loyalitas dalam konteks koneksi WebSocket tunggal.

Untuk beberapa koneksi WebSocket dan setelahnya, Anda dapat mengonfigurasi layanan Cloud Run untuk menggunakan afinitas sesi, tetapi tindakan ini memberikan afinitas upaya terbaik, sehingga WebSockets meminta masih berpotensi muncul di instance yang berbeda. Klien yang terhubung ke layanan Cloud Run Anda mungkin akan dilayani oleh berbagai instance yang tidak mengoordinasikan atau berbagi data.

Untuk mengurangi hal ini, Anda perlu menggunakan penyimpanan data eksternal untuk menyinkronkan status antara instance Cloud Run, yang dijelaskan di bagian berikutnya.

Menyinkronkan data antar-instance

Anda perlu menyinkronkan data untuk memastikan klien yang terhubung ke layanan Cloud Run menerima data yang sama dari koneksi WebSockets.

Misalnya, Anda membuat layanan ruang chat menggunakan WebSockets dan menetapkan setelan konkurensi maksimum ke 1000. Jika lebih dari 1000 pengguna terhubung ke layanan ini secara bersamaan, mereka akan dilayani oleh instance yang berbeda Oleh karena itu, mereka tidak akan dapat melihat pesan yang sama di ruang chat singkat ini.

Untuk menyinkronkan data antara instance Cloud Run Anda, seperti menerima pesan yang diposting ke ruang chat dari semua instance, Anda memerlukan sistem penyimpanan data eksternal, seperti database atau antrean pesan.

Jika menggunakan database eksternal seperti Cloud SQL, Anda dapat mengirim pesan ke database dan melakukan polling dari database secara berkala. Namun perlu diperhatikan bahwa instance Cloud Run tidak memiliki CPU saat container tidak menangani permintaan apa pun. Jika layanan Anda utamanya menangani permintaan WebSocket, kontainer akan memiliki CPU yang dialokasikan selama tersedia setidaknya satu klien yang terhubung dengannya.

Antrean pesan berfungsi lebih baik untuk menyinkronkan data antar container Cloud Run secara real-time, karena antrean pesan eksternal tidak dapat menangani setiap instance untuk "push" data. Layanan Anda perlu "pull" pesan baru dari antrean pesan dengan membuat koneksi ke antrean pesan.

Google merekomendasikan agar Anda menggunakan sistem antrean pesan eksternal seperti Redis Pub/Sub (Memorystore) atau update real-time Firestore yang dapat mengirimkan update ke semua instance melalui koneksi yang dimulai oleh instance container.

Menggunakan Pub/Sub Redis

Arsitektur layanan ruang chat WebSockets

Anda dapat menggunakan mekanisme Redis Pub/Sub dengan membuat instance Redis dari Memorystore. Jika Anda menggunakan library Socket.IO untuk WebSocket, Anda dapat menggunakan adaptor redis.

Di dalam arsitektur berbasis Redis ini, setiap instance Cloud Run menghubungkan koneksi jangka panjang ke saluran Redis yang berisi pesan yang diterima (menggunakan perintah SUBSCRIBE). Setelah instance container menerima pesan baru di saluran, mereka dapat mengirimkannya ke klien melalui WebSocket secara real-time.

Demikian pula, saat klien memunculkan pesan menggunakan WebSocket, instance yang menerima pesan tersebut akan memublikasikan pesan ke saluran Redis (menggunakanPUBLISH perintah), dan instance lain yang berlangganan saluran ini akan menerima pesan ini.

Jika Anda menginginkan panduan kode lengkap, contoh kode tambahan tersedia di topik Tutorial Membuat layanan WebSocket Chat untuk Cloud Run.