Tips & Trik
Dokumen ini berisi penjelasan mengenai praktik terbaik untuk mendesain, mengimplementasikan, menguji, dan men-deploy fungsi Cloud Run.
Ketepatan
Bagian ini menjelaskan praktik terbaik umum untuk merancang dan mengimplementasikan fungsi Cloud Run.
Menulis fungsi idempoten
Fungsi Anda harus memberikan hasil yang sama sekalipun dipanggil berkali-kali. Dengan demikian, Anda dapat mencoba ulang pemanggilan jika pemanggilan sebelumnya gagal di tengah jalan akibat masalah pada kode Anda. Untuk mengetahui informasi selengkapnya, lihat mencoba ulang fungsi berdasarkan peristiwa.
Memastikan fungsi HTTP mengirimkan respons HTTP
Jika fungsi Anda dipicu HTTP, jangan lupa untuk mengirim respons HTTP, seperti yang ditunjukkan di bawah ini. Jika tidak dilakukan, fungsi dapat dieksekusi hingga waktu tunggu habis. Jika hal ini terjadi, Anda akan dikenakan biaya untuk seluruh waktu tunggu. Waktu tunggu juga dapat menyebabkan perilaku yang tidak dapat diprediksi atau cold start pada pemanggilan berikutnya, yang mengakibatkan perilaku yang tidak dapat diprediksi atau latensi tambahan.
Node.js
Python
Go
Java
C#
Ruby
PHP
Jangan memulai aktivitas latar belakang
Aktivitas latar belakang meliputi segala sesuatu yang terjadi setelah fungsi Anda dihentikan.
Pemanggilan fungsi dianggap selesai setelah fungsi tersebut menampilkan atau menandakan penyelesaian, misalnya dengan memanggil argumen callback
di fungsi berdasarkan peristiwa Node.js. Setiap kode yang dijalankan setelah penghentian normal tidak dapat mengakses CPU dan tidak akan diproses.
Selain itu, ketika pemanggilan berikutnya dijalankan di lingkungan yang sama, aktivitas latar belakang Anda akan dilanjutkan, dan itu akan mengganggu pemanggilan baru. Hal ini dapat menyebabkan perilaku yang tidak terduga dan error yang sulit untuk didiagnosis. Mengakses jaringan setelah suatu fungsi berakhir biasanya menyebabkan koneksi disetel ulang (kode error ECONNRESET
).
Aktivitas latar belakang sering kali dapat dideteksi dalam log dari pemanggilan individu, dengan menemukan hal apa pun yang dicatat dalam log setelah baris yang menyatakan bahwa pemanggilan selesai. Aktivitas latar belakang terkadang dapat diletakkan lebih dalam di kode, terutama ketika terdapat operasi asinkron seperti callback atau timer. Tinjau kode Anda untuk memastikan semua operasi asinkron selesai sebelum fungsi dihentikan.
Selalu hapus file sementara
Penyimpanan disk lokal di direktori sementara adalah sistem file dalam memori. File yang Anda tulis menggunakan memori yang disediakan untuk fungsi Anda, dan terkadang tetap dipertahankan di antara pemanggilan. Jika file ini tidak dihapus secara eksplisit, dapat terjadi error kehabisan memori yang disusul dengan cold start.
Anda dapat melihat memori yang digunakan oleh setiap fungsi dengan memilihnya pada daftar fungsi di Konsol Google Cloud dan memilih plot Memory usage.
Usahakan tidak menulis di luar direktori sementara, dan pastikan untuk menggunakan metode yang tidak bergantung pada platform/OS untuk membuat jalur file.
Anda dapat mengurangi persyaratan memori saat memproses file yang lebih besar menggunakan pipeline. Misalnya, Anda dapat memproses file di Cloud Storage dengan membuat aliran data baca, meneruskannya melalui proses berbasis aliran data, dan menuliskan aliran data output langsung ke Cloud Storage.
Functions Framework
Saat Anda men-deploy suatu fungsi, Functions Framework akan otomatis ditambahkan sebagai dependensi menggunakan versi saat ini. Untuk memastikan dependensi yang sama diinstal secara konsisten di berbagai lingkungan, sebaiknya sematkan fungsi Anda ke versi Functions Framework tertentu.
Untuk melakukannya, sertakan versi pilihan Anda dalam file kunci yang relevan
(misalnya, package-lock.json
untuk Node.js, atau requirements.txt
untuk Python).
Alat
Bagian ini berisi panduan cara menggunakan alat untuk mengimplementasikan, menguji, dan berinteraksi dengan fungsi Cloud Run.
Pengembangan lokal
Deployment fungsi memerlukan waktu cukup lama. Jadi, sebaiknya lakukan pengujian kode fungsi secara lokal karena durasinya bisa lebih cepat.
Pelaporan error
Dalam bahasa yang menggunakan penanganan pengecualian, jangan menampilkan pengecualian yang tidak tertangkap, karena pengecualian tersebut memaksa cold start pada pemanggilan di berikutnya. Lihat panduan Pelaporan Error untuk mendapatkan informasi tentang cara melaporkan error dengan benar.
Jangan keluar secara manual
Keluar secara manual dapat menyebabkan perilaku yang tidak terduga. Sebagai gantinya, gunakan idiom spesifik bahasa berikut:
Node.js
Jangan gunakan process.exit()
. Fungsi HTTP harus mengirimkan respons dengan res.status(200).send(message)
, dan fungsi berbasis peristiwa akan keluar setelah fungsi tersebut ditampilkan (baik secara implisit maupun eksplisit).
Python
Jangan gunakan sys.exit()
. Fungsi HTTP harus secara eksplisit menampilkan respons sebagai string, dan fungsi yang dipicu peristiwa akan keluar setelah fungsi tersebut menampilkan nilai (baik secara implisit maupun eksplisit).
Go
Jangan gunakan os.Exit()
. Fungsi HTTP harus secara eksplisit menampilkan respons sebagai string, dan fungsi yang dipicu peristiwa akan keluar setelah fungsi tersebut menampilkan nilai (baik secara implisit maupun eksplisit).
Java
Jangan gunakan System.exit()
. Fungsi HTTP harus mengirimkan respons dengan response.getWriter().write(message)
, dan fungsi berbasis peristiwa akan keluar setelah fungsi tersebut ditampilkan (baik secara implisit maupun eksplisit).
C#
Jangan gunakan System.Environment.Exit()
. Fungsi HTTP harus mengirimkan respons dengan context.Response.WriteAsync(message)
, dan fungsi berbasis peristiwa akan keluar setelah fungsi tersebut ditampilkan (baik secara implisit maupun eksplisit).
Ruby
Jangan gunakan exit()
atau abort()
. Fungsi HTTP harus secara eksplisit menampilkan respons sebagai string, dan fungsi yang dipicu peristiwa akan keluar setelah fungsi tersebut menampilkan nilai (baik secara implisit maupun eksplisit).
PHP
Jangan gunakan exit()
atau die()
. Fungsi HTTP harus secara eksplisit menampilkan respons sebagai string, dan fungsi yang dipicu peristiwa akan keluar setelah fungsi tersebut menampilkan nilai (baik secara implisit maupun eksplisit).
Menggunakan Sendgrid untuk mengirim email
Fungsi Cloud Run tidak mengizinkan koneksi keluar pada port 25, sehingga Anda tidak dapat membuat koneksi tidak aman ke server SMTP. Cara yang direkomendasikan untuk mengirim email adalah dengan menggunakan SendGrid. Anda dapat menemukan opsi lain untuk mengirim email dalam tutorial Mengirim Email dari Instance untuk Google Compute Engine.
Performa
Bagian ini menjelaskan praktik terbaik untuk mengoptimalkan performa.
Menggunakan dependensi dengan bijak
Karena fungsi bersifat stateless, lingkungan eksekusi biasanya diinisialisasi sejak awal (selama periode yang disebut cold start). Saat terjadi cold start, konteks global fungsi akan dievaluasi.
Jika fungsi Anda mengimpor modul, waktu pemuatan untuk modul tersebut dapat meningkatkan latensi pemanggilan selama cold start. Anda dapat mengurangi latensi ini dan waktu yang diperlukan untuk men-deploy fungsi. Caranya, dengan memuat dependensi secara benar dan tidak memuat dependensi yang tidak digunakan fungsi Anda.
Menggunakan variabel global untuk menggunakan kembali objek dalam pemanggilan selanjutnya
Tidak ada jaminan bahwa status fungsi Cloud Run akan dipertahankan untuk pemanggilan selanjutnya. Namun, fungsi Cloud Run sering mendaur ulang lingkungan eksekusi dari pemanggilan sebelumnya. Jika Anda mendeklarasikan sebuah variabel dalam cakupan global, nilainya dapat digunakan kembali dalam pemanggilan selanjutnya tanpa harus dikomputasi ulang.
Dengan begitu, Anda dapat melakukan caching untuk objek yang mungkin memakan biaya tinggi jika harus dibuat ulang di setiap pemanggilan fungsi. Pemindahan objek semacam ini dari isi fungsi ke cakupan global dapat menghasilkan peningkatan performa secara signifikan. Contoh berikut membuat objek berat hanya satu kali per instance fungsi, dan membagikannya ke semua pemanggilan fungsi yang mencapai instance tersebut:
Node.js
Python
Go
Java
C#
Ruby
PHP
Sangatlah penting untuk menyimpan koneksi jaringan, referensi library, dan objek klien API ke dalam cache pada cakupan global. Untuk mendapatkan contoh, baca bagian Mengoptimalkan Jaringan.
Menginisialisasi variabel global berdasarkan permintaan
Jika Anda menginisialisasi variabel dalam cakupan global, kode inisialisasi akan selalu dijalankan melalui pemanggilan cold start, sehingga latensi fungsi Anda meningkat.
Dalam kasus tertentu, hal ini menyebabkan waktu tunggu yang terputus-putus pada layanan yang sedang dipanggil jika variabel tersebut tidak ditangani dengan benar dalam blok try
/catch
. Jika beberapa objek tidak digunakan di semua jalur kode, sebaiknya lakukan inisialisasi berdasarkan permintaan:
Node.js
Python
Go
Java
C#
Ruby
PHP
Fungsi PHP tidak dapat mempertahankan variabel di antara permintaan. Contoh cakupan di atas menggunakan pemuatan lambat untuk meng-cache nilai variabel global dalam file.
Hal ini sangat penting jika Anda menetapkan beberapa fungsi dalam satu file, dan fungsi yang berbeda menggunakan variabel yang berbeda. Jika tidak menggunakan inisialisasi berdasarkan permintaan, Anda dapat menyia-nyiakan resource pada variabel yang telah diinisialisasi tapi tidak pernah digunakan.
Mengurangi cold start dengan menetapkan jumlah minimum instance
Secara default, fungsi Cloud Run menskalakan jumlah instance berdasarkan jumlah permintaan yang masuk. Anda dapat mengubah perilaku default ini dengan menetapkan jumlah minimum instance yang harus selalu disiapkan oleh fungsi Cloud Run untuk menyalurkan permintaan. Menetapkan jumlah minimum instance akan mengurangi cold start pada aplikasi Anda. Sebaiknya tetapkan jumlah minimum instance jika aplikasi Anda sensitif terhadap latensi.
Untuk mempelajari cara menetapkan jumlah instance minimum, baca Menggunakan instance minimum.
Referensi lainnya
Cari tahu selengkapnya tentang pengoptimalan performa di video "Google Cloud Performance Atlas" Cloud Run functions Cold Boot Time.