Panduan ini menyediakan praktik terbaik untuk merancang, mengimplementasikan, menguji, dan men-deploy layanan Cloud Run. Untuk tips lainnya, lihat Memigrasikan Layanan yang Sudah Ada.
Menulis layanan yang efektif
Bagian ini menjelaskan praktik terbaik umum untuk merancang dan mengimplementasikan layanan Cloud Run.
Aktivitas latar belakang
Aktivitas latar belakang meliputi segala sesuatu yang terjadi setelah respons HTTP dikirimkan. Untuk mengetahui apakah ada aktivitas latar belakang dalam layanan Anda yang tidak terlihat dengan jelas, periksa log Anda untuk mencari hal-hal yang tercatat setelah entri untuk permintaan HTTP.
Mengonfigurasi CPU agar selalu dialokasikan untuk menggunakan aktivitas latar belakang
Jika Anda ingin mendukung aktivitas latar belakang di layanan Cloud Run, setel CPU layanan Cloud Run agar selalu dialokasikan. Hal ini memungkinkan Anda menjalankan aktivitas latar belakang di luar permintaan dan tetap memiliki akses CPU.
Menghindari aktivitas latar belakang jika CPU dialokasikan hanya selama pemrosesan permintaan
Jika Anda ingin mengatur layanan agar hanya mengalokasikan CPU selama pemrosesan permintaan, perlu diingat bahwa ketika layanan Cloud Run telah selesai menangani permintaan, akses ke CPU di instance akan dinonaktifkan atau sangat terbatas. Jika menggunakan jenis alokasi CPU ini, Anda tidak boleh memulai thread atau rutinitas latar belakang yang berjalan di luar cakupan pengendali permintaan.
Tinjau kode Anda untuk memastikan semua operasi asinkron selesai sebelum Anda mengirimkan respons.
Menjalankan thread latar belakang dengan alokasi CPU jenis ini dapat mengakibatkan perilaku yang tidak terduga karena permintaan berikutnya ke instance container yang sama akan melanjutkan aktivitas latar belakang yang ditangguhkan.
Menghapus file sementara
Di lingkungan Cloud Run, penyimpanan disk berfungsi sebagai sistem file dalam memori. File yang ditulis ke disk menggunakan memori yang seharusnya disediakan untuk layanan Anda, dan bisa tetap dipertahankan di antara pemanggilan. Jika file ini tidak dihapus, dapat terjadi error kehabisan memori yang disusul dengan cold start.
Melaporkan error
Tangani semua pengecualian dan jangan biarkan layanan Anda tidak bekerja saat terjadi error. Error akan menyebabkan cold start saat traffic diantrekan untuk instance pengganti.
Lihat Panduan pelaporan error untuk mendapatkan informasi tentang cara melaporkan error dengan benar.
Mengoptimalkan performa
Bagian ini menjelaskan praktik terbaik untuk mengoptimalkan performa.
Memulai container dengan cepat
Karena instance diskalakan sesuai kebutuhan, waktu startup-nya berdampak pada latensi layanan Anda. Meskipun Cloud Run memisahkan startup instance dan pemrosesan permintaan, bisa saja terjadi suatu permintaan harus menunggu instance baru dimulai untuk diproses, terutama terjadi saat melakukan peningkatan dari nol. Hal ini disebut "cold start".
Rutinitas startup terdiri dari:
- Mendownload image container (menggunakan teknologi streaming image container Cloud Run)
- Memulai container dengan menjalankan perintah entrypoint.
- Menunggu container mulai memproses port yang dikonfigurasi.
Mengoptimalkan kecepatan startup container akan meminimalkan latensi pemrosesan permintaan.
Menggunakan peningkatan CPU startup untuk mengurangi latensi startup
Anda dapat mengaktifkan peningkatan CPU startup untuk meningkatkan alokasi CPU untuk sementara waktu selama startup instance guna mengurangi latensi startup.
Menggunakan instance minimum untuk mengurangi cold start
Anda dapat mengonfigurasi instance minimum dan konkurensi untuk meminimalkan cold start. Misalnya, dengan menggunakan instance minimum 1 berarti layanan Anda siap menerima hingga jumlah permintaan serentak yang dikonfigurasi untuk layanan Anda tanpa perlu memulai instance baru.
Perhatikan bahwa permintaan yang menunggu instance dimulai akan tetap tertunda dalam antrean sebagai berikut:
- Jika instance baru dimulai, seperti selama penskalaan keluar, permintaan akan tertunda setidaknya selama waktu startup rata-rata instance penampung layanan ini. Hal ini mencakup saat permintaan memulai penskalaan keluar, seperti saat penskalaan dari nol.
- Jika waktu startup kurang dari 10 detik, permintaan akan ditangguhkan hingga 10 detik.
- Jika tidak ada instance yang sedang dalam proses dimulai, dan permintaan tidak memulai penskalaan keluar, permintaan akan ditangguhkan hingga 10 detik.
Menggunakan dependensi dengan bijak
Jika Anda menggunakan bahasa dinamis dengan library dependen, seperti mengimpor modul di Node.js, waktu pemuatan untuk modul tersebut akan ditambahkan ke latensi startup.
Kurangi latensi startup dengan cara berikut:
- Minimalkan jumlah dan ukuran dependensi untuk mem-build layanan yang efisien.
- Memuat kode yang jarang digunakan secara lambat, jika bahasa Anda mendukung fitur ini.
- Gunakan pengoptimalan pemuatan kode seperti pengoptimalan autoloader composer pada PHP.
Menggunakan variabel global
Di Cloud Run, Anda tidak dapat berasumsi bahwa status layanan dipertahankan di antara permintaan. Namun, Cloud Run menggunakan kembali setiap instance untuk menyalurkan traffic yang sedang berlangsung. Oleh karena itu Anda dapat mendeklarasikan variabel dalam cakupan global agar nilainya dapat digunakan kembali dalam pemanggilan selanjutnya. Tidak dapat diprediksi sebelumnya apakah setiap permintaan menerima manfaat dari penggunaan ulang ini.
Anda juga dapat menyimpan cache objek di memori jika objek tersebut mahal untuk dibuat ulang pada setiap permintaan layanan. Memindahkan tindakan ini dari logika permintaan ke cakupan global akan menghasilkan performa yang lebih baik.
Node.js
Python
Go
Java
Melakukan inisialisasi lambat untuk variabel global
Inisialisasi variabel global selalu terjadi selama startup, yang dapat meningkatkan waktu cold start. Gunakan inisialisasi lambat untuk objek yang jarang digunakan guna menunda biaya dan mengurangi waktu cold start.
Salah satu kelemahan inisialisasi lambat adalah peningkatan latensi untuk permintaan pertama ke instance baru. Hal ini dapat menyebabkan penskalaan berlebih dan permintaan yang dihapus saat Anda men-deploy revisi baru layanan yang secara aktif menangani banyak permintaan.
Node.js
Python
Go
Java
Menggunakan lingkungan eksekusi yang berbeda
Anda mungkin mengalami waktu startup yang lebih cepat dengan menggunakan lingkungan eksekusi yang berbeda.
Mengoptimalkan konkurensi
Instance Cloud Run dapat menyajikan beberapa permintaan secara bersamaan, "secara serentak", hingga konkurensi maksimum yang dapat dikonfigurasi.
Hal ini berbeda dengan fungsi Cloud Run, yang menggunakan concurrency = 1
.
Cloud Run secara otomatis menyesuaikan konkurensi hingga batas maksimum yang dikonfigurasi.
Batas konkurensi maksimum default 80 cocok untuk banyak image container. Namun, Anda harus:
- Turunkan nilai jika container Anda tidak dapat memproses banyak permintaan serentak.
- Naikkan batas ini jika container Anda mampu menangani permintaan dalam jumlah besar.
Menyesuaikan konkurensi untuk layanan Anda
Jumlah permintaan serentak yang dapat dilayani oleh setiap instance dapat dibatasi oleh technology stack dan penggunaan resource bersama seperti variabel dan koneksi database.
Untuk mengoptimalkan layanan Anda agar mencapai konkurensi maksimum yang stabil:
- Optimalkan performa layanan Anda.
- Tetapkan tingkat dukungan konkurensi yang diharapkan dalam konfigurasi konkurensi tingkat kode apa pun. Tidak semua technology stack memerlukan setelan tersebut.
- Deploy layanan Anda.
- Setel tingkat konkurensi Cloud Run untuk layanan Anda agar sesuai atau kurang dari konfigurasi tingkat kode apa pun. Jika tidak ada konfigurasi tingkat kode, gunakan konkurensi yang diharapkan.
- Gunakan alat pengujian beban yang mendukung konkurensi yang dapat dikonfigurasi. Anda perlu memastikan bahwa layanan Anda tetap stabil di bawah beban dan konkurensi yang diharapkan.
- Jika layanan tidak berfungsi dengan baik, lanjutkan ke langkah 1 untuk meningkatkan layanan atau langkah 2 untuk mengurangi konkurensi. Jika layanan berfungsi dengan baik, kembali ke langkah 2 dan tingkatkan konkurensi.
Lanjutkan iterasi sampai Anda menemukan konkurensi maksimum yang stabil.
Mencocokkan memori dengan konkurensi
Setiap permintaan yang ditangani layanan Anda memerlukan sejumlah memori tambahan. Jadi, saat menyesuaikan konkurensi ke atas atau ke bawah, pastikan Anda juga menyesuaikan batas memori.
Menghindari status global yang dapat berubah
Jika ingin memanfaatkan status global yang dapat berubah dalam konteks konkurensi, pastikan mengambil langkah tambahan dalam kode Anda untuk memastikan hal ini dilakukan dengan aman. Untuk menghindari konflik, sebaiknya batasi variabel global dengan inisialisasi satu kali dan gunakan kembali, seperti yang dijelaskan di bagian Performa di atas.
Jika Anda menggunakan variabel global yang dapat diubah dalam layanan yang menangani beberapa permintaan secara bersamaan, pastikan untuk menggunakan kunci atau mutex untuk menghindari kondisi race.
Kompromi throughput versus latensi versus biaya
Menyesuaikan setelan permintaan serentak maksimum dapat membantu menyeimbangkan kompromi antara throughput, latensi, dan biaya untuk layanan Anda.
Secara umum, setelan permintaan serentak maksimum yang lebih rendah akan menghasilkan latensi yang lebih rendah dan throughput yang lebih rendah per instance. Dengan permintaan serentak maksimum yang lebih rendah, lebih sedikit permintaan yang bersaing untuk mendapatkan resource di dalam setiap instance dan setiap permintaan mencapai performa yang lebih baik. Namun, karena setiap instance dapat menyalurkan lebih sedikit permintaan sekaligus, throughput per instance lebih rendah dan layanan memerlukan lebih banyak instance untuk menyalurkan traffic yang sama.
Sebaliknya, setelan permintaan serentak maksimum yang lebih tinggi umumnya menghasilkan latensi yang lebih tinggi dan throughput yang lebih tinggi per instance. Permintaan mungkin perlu menunggu akses ke resource seperti CPU, GPU, dan bandwidth memori di dalam instance, yang menyebabkan peningkatan latensi. Namun, setiap instance dapat memproses lebih banyak permintaan sekaligus sehingga layanan memerlukan lebih sedikit instance secara keseluruhan untuk memproses traffic yang sama.
Pertimbangan biaya
Penagihan Cloud Run adalah per waktu instance. Jika CPU selalu dialokasikan, waktu instance adalah total masa aktif setiap instance. Jika CPU tidak selalu dialokasikan, waktu instance adalah waktu yang dihabiskan setiap instance untuk memproses setidaknya satu permintaan.
Dampak permintaan serentak maksimum terhadap penagihan bergantung pada pola traffic Anda. Menurunkan permintaan serentak maksimum dapat menghasilkan tagihan yang lebih rendah jika setelan yang lebih rendah menyebabkan
- Menurunkan latensi
- Instance menyelesaikan pekerjaannya lebih cepat
- Instance dinonaktifkan lebih cepat meskipun total instance yang diperlukan lebih banyak
Namun, hal sebaliknya juga dapat terjadi: menurunkan permintaan serentak maksimum dapat meningkatkan penagihan jika peningkatan jumlah instance tidak diimbangi dengan pengurangan waktu yang diperlukan setiap instance untuk berjalan, karena latensi yang lebih baik.
Cara terbaik untuk mengoptimalkan penagihan adalah melalui pengujian beban menggunakan setelan permintaan serentak maksimum yang berbeda untuk mengidentifikasi setelan yang menghasilkan waktu instance yang dapat ditagih terendah, seperti yang terlihat dalam metrik pemantauan container/billable_instance_time.
Keamanan container
Sebagian besar praktik keamanan software yang umum digunakan juga berlaku untuk aplikasi yang dijalankan dalam container. Ada beberapa praktik yang entah khusus untuk kontainer atau sesuai dengan filosofi dan arsitektur dari kontainer.
Untuk meningkatkan keamanan container:
Gunakan image dasar yang dikelola secara aktif dan aman, seperti image dasar Google atau image resmi Docker Hub.
Terapkan update keamanan pada layanan Anda dengan mem-build ulang image container secara rutin dan men-deploy ulang layanan Anda.
Sertakan hanya hal yang diperlukan ke dalam container untuk menjalankan layanan Anda. Kode, paket, dan alat tambahan dapat berpotensi terhadap kerentanan keamanan. Lihat di atas untuk dampak performa yang terkait.
Implementasikan proses build deterministik yang menyertakan versi software dan library tertentu. Langkah ini mencegah kode yang tidak terverifikasi untuk dimasukkan ke dalam kontainer Anda.
Atur container Anda untuk dijalankan sebagai pengguna selain
root
dengan pernyataanUSER
Dockerfile. Beberapa image kontainer mungkin sudah memiliki pengguna tertentu yang telah dikonfigurasi sebelumnya.Cegah penggunaan fitur Pratinjau menggunakan kebijakan organisasi kustom.
Mengotomatiskan pemindaian keamanan
Aktifkan pemindaian kerentanan untuk pemindaian keamanan image container yang disimpan di Artifact Registry.
Mem-build image container minimal
Image container besar cenderung meningkatkan kerentanan keamanan karena mengandung lebih dari yang diperlukan oleh kode.
Berkat teknologi streaming image container Cloud Run, ukuran image container Anda tidak memengaruhi cold start atau waktu pemrosesan permintaan. Ukuran image container juga tidak mengurangi memori yang tersedia untuk container Anda.
Untuk mem-build container minimal, sebaiknya gunakan image dasar yang efisien seperti:
Ubuntu berukuran lebih besar, tetapi merupakan image dasar yang biasa digunakan dengan lingkungan server siap pakai dan lebih lengkap.
Jika layanan Anda memiliki proses build dengan banyak alat, pertimbangkan untuk menggunakan build multi-stage agar container tetap ringan saat dijalankan.
Referensi ini memberikan informasi lebih lanjut tentang cara membuat image container yang efisien:
- Praktik terbaik Kubernetes: Cara dan alasan build image container kecil
- 7 praktik terbaik untuk membuat container