Tips & trik

Dokumen ini berisi penjelasan mengenai praktik terbaik untuk merancang, mengimplementasikan, menguji, dan menerapkan Cloud Functions.

Ketepatan

Bagian ini menjelaskan praktik terbaik yang umum untuk merancang dan mengimplementasikan Cloud Functions.

Menuliskan 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 lebih lanjut, baca artikel mencoba ulang fungsi background.

Jangan memulai kegiatan background

Aktivitas background 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 background Node.js. Kode apa pun yang berjalan setelah penghentian tidak dapat mengakses CPU dan tidak akan membuat kemajuan.

Selain itu, ketika pemanggilan berikutnya dijalankan di lingkungan yang sama, aktivitas background 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 background seringkali dapat dideteksi dalam log dari pemanggilan individu, dengan menemukan hal apa pun yang dicatat dalam log setelah baris yang menyatakan bahwa pemanggilan selesai. Aktivitas background 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 ada di antara permintaan. Jika file ini tidak dihapus, pada akhirnya akan terjadi error kehabisan memori dan disusul dengan start cold.

Anda dapat melihat memori yang digunakan oleh setiap fungsi dengan memilihnya pada daftar fungsi di Konsol GCP dan memilih plot Penggunaan memori.

Usahakan tidak menulis di luar direktori sementara dan pastikan untuk menggunakan metode yang bergantung pada platform/OS untuk membangun lokasi file.

Anda dapat melewati batasan ukuran pada file sementara dengan menggunakan pipeline. Misalnya, Anda dapat memproses file di Cloud Storage dengan membuat stream baca, meneruskannya melalui proses berbasis stream, dan menuliskan stream output langsung ke Cloud Storage.

Fitur

Bagian ini berisi panduan cara menggunakan fitur untuk mengimplementasikan, menguji, dan berinteraksi dengan Cloud Functions.

Pengembangan lokal

Penerapan fungsi memerlukan waktu beberapa lama, sehingga sering lebih cepat untuk menguji kode fungsi Anda secara lokal menggunakan shim.

Sebaiknya gunakan Emulator Node.js Cloud Functions sebagai shim.

Menggunakan Sendgrid untuk mengirim email

Cloud Functions 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 contoh lengkap di Tutorial SendGrid dan opsi pengiriman email lainnya dalam dokumen Google Compute Engine mengenai cara Mengirimkan Email dari Instance.

Performa

Bagian ini menjelaskan praktik terbaik untuk mengoptimalkan performa.

Menggunakan dependensi dengan bijak

Karena fungsi bersifat stateless, lingkungan eksekusi biasanya diinisialisasi dari awal sekali (selama periode yang disebut start cold). Saat terjadi start cold, konteks global dari fungsi tersebut akan dievaluasi.

Jika fungsi Anda mengimpor modul, waktu muat untuk modul tersebut dapat ditambahkan ke latensi pemanggilan selama start cold. Anda dapat mengurangi latensi ini, serta waktu yang diperlukan untuk menerapkan fungsi, dengan memuat dependensi dengan 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 Cloud Functions akan dipertahankan untuk pemanggilan selanjutnya. Namun, Cloud Functions sering mendaur ulang lingkungan eksekusi dari pemanggilan sebelumnya. Jika Anda menyatakan sebuah variabel dalam cakupan global, nilainya dapat digunakan kembali dalam pemanggilan selanjutnya tanpa harus dikomputasi ulang.

Dengan begitu, Anda dapat menyimpan objek ke dalam cache yang mungkin saja mahal untuk dibuat ulang di setiap pemanggilan fungsi. Pemindahan objek dari isi fungsi ke cakupan global semacam ini 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 tertentu:

console.log('Global scope');
const perInstance = heavyComputation();
const functions = require('firebase-functions');

exports.function = functions.https.onRequest((req, res) => {
    console.log('Function invocation');
    const perFunction = lightweightComputation();

    res.send(`Per instance: ${perInstance}, per function: ${perFunction}`);
});

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 start cold, sehingga latensi fungsi Anda meningkat. Jika beberapa objek tidak digunakan di semua lokasi kode, pertimbangkan untuk melakukan inisialisasi berdasarkan permintaan:

const functions = require('firebase-functions');
let myCostlyVariable;

exports.function = functions.https.onRequest((req, res) => {
    doUsualWork();
    if(unlikelyCondition()){
        myCostlyVariable = myCostlyVariable || buildCostlyVariable();
    }
    res.status(200).send('OK');
});

Hal ini sangat penting jika Anda menetapkan beberapa fungsi dalam satu file, dan fungsi yang berbeda menggunakan variabel yang berbeda. Kecuali jika Anda menggunakan inisialisasi berdasarkan permintaan, Anda dapat menyia-nyiakan resource pada variabel yang diinisialisasi, tapi belum pernah digunakan.

Referensi tambahan

Cari tahu selengkapnya tentang pengoptimalan performa di video "Google Cloud Performance Atlas" Cloud Functions Cold Boot Time.

Kirim masukan tentang...

Butuh bantuan? Kunjungi halaman dukungan kami.