Memecahkan masalah peningkatan latensi di aplikasi

Dalam banyak kasus, peningkatan latensi dalam aplikasi Anda pada akhirnya akan menyebabkan error server 5xx. Oleh karena itu, masuk akal untuk mengikuti serangkaian langkah pemecahan masalah yang serupa untuk mempersempit penyebab utama lonjakan error dan latensi, mengingat penyebabnya masing-masing mungkin sama.

Menentukan cakupan masalah

Pertama, tentukan cakupan masalah sesempit mungkin dengan mengumpulkan informasi yang relevan. Di bawah ini beberapa saran untuk informasi yang mungkin relevan.

  • ID, layanan, dan versi aplikasi apa yang terpengaruh?
  • Endpoint spesifik mana pada aplikasi yang terpengaruh?
  • Apakah hal ini berdampak terhadap semua klien secara global, atau sebagian klien tertentu?
  • Kapan waktu mulai dan waktu berakhir insiden tersebut? Anda harus menentukan zona waktu.
  • Error spesifik apa yang Anda lihat?
  • Apa yang dimaksud dengan delta latensi yang diamati, yang biasanya ditentukan sebagai peningkatan pada persentil tertentu? Misalnya, latensi meningkat sebesar 2 detik pada persentil ke-90.
  • Bagaimana Anda mengukur latensi? Secara khusus, apakah metrik tersebut diukur pada klien atau terlihat di data latensi Cloud Logging dan/atau Cloud Monitoring yang disediakan oleh infrastruktur penayangan App Engine?
  • Apa dependensi aplikasi Anda dan apakah ada yang mengalami insiden?
  • Apakah Anda baru-baru ini membuat perubahan kode, konfigurasi, atau workload yang dapat memicu masalah ini?

Aplikasi mungkin memiliki monitoring dan logging kustom sendiri yang dapat Anda gunakan untuk lebih mempersempit cakupan masalah di luar saran di atas. Dengan menentukan cakupan masalah, Anda dapat mencari kemungkinan penyebab utama dan menentukan langkah pemecahan masalah selanjutnya.

Menentukan apa yang gagal

Selanjutnya, tentukan komponen mana di jalur permintaan yang paling mungkin menyebabkan latensi atau error. Komponen utama dalam jalur permintaan adalah:

Klien -> Internet -> Google Front End (GFE) -> App Engine yang menyediakan infrastruktur -> Instance aplikasi

Jika informasi yang dikumpulkan pada langkah #1 tidak menunjukkan sumber kegagalan, biasanya Anda harus memulai dengan memeriksa kondisi dan performa instance aplikasi Anda.

Salah satu cara untuk menentukan apakah masalahnya ada pada instance aplikasi atau tidak adalah dengan melihat log permintaan App Engine: jika Anda melihat error kode status HTTP atau latensi yang meningkat di log tersebut, umumnya berarti masalah tersebut terletak pada instance yang menjalankan aplikasi Anda.

Ada satu skenario yang meningkatkan error dan latensi di log permintaan yang mungkin tidak disebabkan oleh instance aplikasi itu sendiri: Jika jumlah instance aplikasi Anda belum ditingkatkan skalanya agar sesuai dengan tingkat traffic, instance mungkin kelebihan beban, sehingga menyebabkan peningkatan error dan latensi.

Jika Anda melihat peningkatan error atau latensi di Cloud Monitoring, secara umum Anda dapat menyimpulkan bahwa masalahnya terletak di upstream load balancer, yang mencatat metrik App Engine. Pada banyak kasus, hal ini mengarah ke masalah dalam instance aplikasi.

Namun, jika Anda melihat peningkatan latensi atau error dalam metrik pemantauan, tetapi tidak pada log permintaan, diperlukan penyelidikan lebih lanjut. Hal ini mungkin menunjukkan kegagalan di lapisan load balancing, atau bahwa instance tersebut mengalami kegagalan parah sehingga load balancer tidak dapat merutekan permintaan ke sana. Untuk membedakan kasus-kasus ini, Anda dapat melihat log permintaan tepat sebelum insiden dimulai. Jika log permintaan menunjukkan peningkatan latensi tepat sebelum kegagalan, hal ini menunjukkan bahwa instance aplikasi itu sendiri mulai gagal sebelum load balancer menghentikan perutean permintaan ke sana.

Skenario yang dapat menyebabkan insiden

Berikut beberapa skenario yang pernah dialami pengguna.

Klien

Memetakan IP klien ke region geografis

Google akan me-resolve nama host untuk aplikasi App Engine ke GFE terdekat dengan klien, berdasarkan alamat IP klien yang digunakan dalam pencarian DNS. Jika DNS resolver klien tidak menggunakan protokol EDNS0, permintaan klien mungkin tidak dirutekan ke GFE terdekat.

Internet

Koneksi internet yang buruk

Jalankan perintah berikut pada klien Anda untuk menentukan apakah masalahnya adalah koneksi internet yang buruk.

$ curl -s -o /dev/null -w '%{time_connect}\n' <hostname>

Nilai untuk time_connect umumnya menunjukkan latensi koneksi klien ke Google Front End terdekat. Jika koneksi ini lambat, Anda dapat memecahkan masalah lebih lanjut menggunakan traceroute untuk menentukan hop mana di jaringan yang menyebabkan penundaan.

Anda dapat menjalankan pengujian dari klien di lokasi geografis yang berbeda. Permintaan akan otomatis dirutekan ke pusat data Google terdekat, yang akan bervariasi berdasarkan lokasi klien.

Klien dengan bandwidth rendah

Aplikasi mungkin merespons dengan cepat, tetapi respons mungkin diperlambat oleh bottleneck jaringan yang menyebabkan infrastruktur penyajian App Engine tidak mengirimkan paket melalui jaringan secepat yang seharusnya.

Google Front End (“GFE”)

Pemblokiran head of line HTTP/2

Klien HTTP/2 yang mengirim beberapa permintaan secara paralel mungkin mengalami peningkatan latensi karena pemblokiran head of line di GFE. Solusi terbaiknya adalah klien harus melakukan upgrade agar dapat menggunakan protokol QUIC.

Penghentian SSL untuk domain kustom

GFE menghentikan koneksi SSL. Hop tambahan diperlukan untuk penghentian SSL jika Anda menggunakan domain kustom, bukan domain appspot.com. Tindakan ini mungkin meningkatkan latensi untuk aplikasi yang berjalan di beberapa region.

Infrastruktur penyajian App Engine

Insiden di tingkat layanan

Google akan memposting detail tentang tingkat layanan yang parah di https://status.cloud.google.com/. Perhatikan bahwa Google melakukan peluncuran secara bertahap, sehingga insiden di tingkat layanan cenderung tidak memengaruhi semua instance sekaligus.

Penskalaan otomatis

Meningkatkan skala traffic terlalu cepat

Penskalaan otomatis App Engine mungkin tidak menskalakan instance Anda secepat peningkatan traffic, sehingga menyebabkan overload sementara. Biasanya, hal ini terjadi saat traffic tidak dihasilkan secara organik oleh pengguna akhir, tetapi dihasilkan oleh program komputer. Cara terbaik untuk mengatasinya adalah dengan men-throttle sistem yang menghasilkan traffic.

Lonjakan traffic

Lonjakan traffic dapat menyebabkan peningkatan latensi jika aplikasi yang diskalakan otomatis perlu ditingkatkan skalanya lebih cepat daripada yang memungkinkan tanpa memengaruhi latensi. Traffic pengguna akhir biasanya tidak menyebabkan lonjakan traffic yang sering. Jika melihat kasus ini, Anda harus menyelidiki apa yang menyebabkan lonjakan traffic tersebut. Jika sistem batch berjalan pada interval, Anda mungkin dapat memperlancar traffic atau menggunakan setelan penskalaan yang berbeda.

Setelan autoscaler

Autoscaler dapat dikonfigurasi berdasarkan karakteristik penskalaan aplikasi Anda. Parameter penskalaan ini mungkin menjadi tidak optimal selama skenario tertentu.

Aplikasi lingkungan fleksibel App Engine diskalakan berdasarkan pemakaian CPU. Namun, aplikasi mungkin terikat I/O selama insiden yang mengakibatkan overload pada instance dengan jumlah permintaan yang tinggi karena penskalaan berbasis CPU tidak terjadi.

Setelan penskalaan lingkungan standar App Engine dapat menyebabkan latensi jika disetel terlalu agresif. Jika Anda melihat respons server dengan kode status 500 dan pesan Request was aborted after waiting too long to attempt to service your request di log Anda, artinya waktu permintaan habis pada antrean tertunda yang menunggu instance tidak ada aktivitas.

Jangan gunakan penskalaan manual lingkungan standar App Engine jika aplikasi Anda menyalurkan traffic pengguna akhir. Penskalaan manual lebih baik untuk workload seperti task queue. Anda mungkin melihat peningkatan waktu tunda dengan penskalaan manual meskipun telah menyediakan instance yang memadai.

Jangan gunakan penskalaan dasar lingkungan standar App Engine untuk aplikasi yang sensitif terhadap latensi. Jenis penskalaan ini dirancang untuk meminimalkan biaya dengan mengorbankan latensi.

Setelan penskalaan default lingkungan standar App Engine memberikan latensi yang optimal untuk sebagian besar aplikasi. Jika masih menemukan adanya permintaan dengan waktu tunda yang tinggi, Anda dapat menentukan jumlah minimum instance. Jika menyesuaikan setelan penskalaan untuk mengurangi biaya dengan meminimalkan instance tanpa aktivitas, Anda berisiko melihat lonjakan latensi jika beban meningkat secara tiba-tiba.

Sebaiknya lakukan tolok ukur performa dengan setelan penskalaan default, lalu jalankan tolok ukur baru setelah setiap perubahan pada setelan ini.

Deployment

Peningkatan latensi sesaat setelah deployment menunjukkan bahwa skala Anda tidak mencukupi sebelum memigrasikan traffic. Instance baru mungkin belum mempersiapkan cache lokal sehingga mungkin disajikan lebih lambat dibandingkan instance lama.

Untuk menghindari lonjakan latensi, jangan men-deploy aplikasi App Engine menggunakan nama versi yang sama dengan versi aplikasi yang sudah ada. Jika menggunakan kembali nama versi yang sudah ada, Anda tidak akan dapat memigrasikan traffic ke versi baru secara perlahan. Permintaan mungkin menjadi lebih lambat karena setiap instance akan dimulai ulang dalam jangka waktu yang singkat. Anda juga harus melakukan deployment ulang jika ingin kembali ke versi sebelumnya.

Instance aplikasi

Kode aplikasi

Masalah dalam kode aplikasi dapat sangat sulit untuk di-debug, terutama jika sifatnya intermiten atau tidak mudah direproduksi. Untuk membantu mendiagnosis masalah, sebaiknya aplikasi Anda diinstrumentasikan menggunakan logging, monitoring, dan tracing. Anda dapat mencoba menggunakan Cloud Profiler untuk mendiagnosis masalah. Lihat contoh cara mendiagnosis latensi permintaan pemuatan menggunakan Cloud Trace untuk mengupload informasi waktu tambahan bagi setiap permintaan.

Anda juga dapat mencoba merekonstruksi masalah di lingkungan pengembangan lokal yang dapat memungkinkan Anda menjalankan alat proses debug bahasa tertentu yang mungkin tidak dapat dijalankan dalam App Engine.

Jika beroperasi di lingkungan fleksibel App Engine, Anda dapat menjalankan SSH ke instance dan melakukan thread dump untuk melihat status aplikasi Anda saat ini. Anda dapat mencoba merekonstruksi masalah ini dalam uji workload atau dengan menjalankan aplikasi secara lokal. Anda dapat menambah ukuran instance untuk melihat apakah tindakan ini dapat menyelesaikan masalah. Misalnya, peningkatan RAM dapat menyelesaikan masalah untuk aplikasi yang mengalami penundaan karena pembersihan sampah memori.

Untuk lebih memahami bagaimana aplikasi Anda gagal dan bottleneck apa yang terjadi, Anda dapat menjalankan uji workload pada aplikasi Anda hingga terjadi kegagalan. Tetapkan jumlah maksimum instance, lalu tingkatkan workload secara bertahap hingga aplikasi gagal.

Jika masalah latensi berkaitan dengan deployment kode aplikasi versi baru, Anda dapat melakukan roll back untuk menentukan apakah versi baru tersebut yang menyebabkan insiden. Jika Anda men-deploy kode terus-menerus, mungkin deployment terjadi cukup sering sehingga sulit menentukan apakah deployment tersebut yang menyebabkan insiden atau tidak berdasarkan waktu onset.

Aplikasi Anda dapat menyimpan setelan konfigurasi dalam Datastore atau di tempat lain. Akan sangat membantu jika Anda dapat membuat linimasa perubahan konfigurasi, guna menentukan apakah ada perubahan yang sesuai dengan dimulainya peningkatan latensi.

Perubahan workload

Perubahan workload dapat menyebabkan peningkatan latensi. Beberapa metrik pemantauan yang dapat menunjukkan perubahan workload mencakup qps serta penggunaan atau latensi API. Anda juga dapat memeriksa perubahan ukuran permintaan dan respons.

Kegagalan health check

Load balancer lingkungan fleksibel App Engine akan berhenti merutekan permintaan ke instance yang gagal dalam health check. Hal ini dapat meningkatkan beban pada instance lain, yang berpotensi menyebabkan kegagalan beruntun. Log Nginx lingkungan fleksibel App Engine menunjukkan instance yang gagal dalam health check. Analisis log dan pemantauan Anda untuk menentukan alasan instance menjadi tidak responsif, atau konfigurasi health check agar tidak terlalu sensitif terhadap kegagalan sementara. Perlu diperhatikan bahwa akan ada penundaan singkat sebelum load balancer berhenti merutekan traffic ke instance yang tidak responsif. Penundaan ini dapat menyebabkan lonjakan error jika load balancer tidak dapat mengajukan ulang permintaan.

Lingkungan standar App Engine tidak menggunakan health check.

Tekanan memori

Jika pemantauan menunjukkan pola gigi gergaji dalam penggunaan memori, atau penurunan penggunaan memori yang berkaitan dengan deployment, masalah performa mungkin disebabkan oleh kebocoran memori. Kebocoran memori dapat menyebabkan pembersihan sampah memori yang sering, sehingga mengakibatkan latensi lebih tinggi. Menyediakan instance lebih banyak dengan memori lebih besar dapat menyelesaikan masalah jika Anda tidak dapat melacaknya dengan mudah ke masalah dalam kode.

Kebocoran resource

Jika instance aplikasi Anda menunjukkan peningkatan latensi yang berhubungan dengan usia instance, mungkin terjadi kebocoran resource yang menyebabkan masalah performa. Dalam jenis masalah ini, Anda juga akan melihat penurunan latensi tepat setelah deployment. Misalnya, struktur data yang menjadi lebih lambat seiring waktu karena penggunaan CPU yang lebih tinggi dapat menyebabkan workload yang terikat ke CPU menjadi lebih lambat.

Pengoptimalan kode

Beberapa cara yang dapat Anda lakukan untuk mengoptimalkan kode di App Engine guna mengurangi latensi:

  • Tugas offline: Gunakan Cloud Tasks agar permintaan pengguna tidak memblokir waktu menunggu penyelesaian tugas, seperti mengirim email.

  • Panggilan API asinkron: Pastikan kode Anda tidak diblokir saat menunggu panggilan API selesai. Library seperti ndb menawarkan dukungan bawaan untuk hal ini.

  • Panggilan Batch API: Panggilan API versi batch biasanya lebih cepat daripada mengirim panggilan satu per satu.

  • Denormalisasi model data: Kurangi latensi panggilan yang dilakukan ke lapisan persistensi data dengan melakukan denormalisasi model data.

Dependensi

Anda dapat memantau dependensi aplikasi agar dapat mendeteksi apakah lonjakan latensi berkorelasi dengan kegagalan dependensi.

Peningkatan latensi untuk dependensi dapat disebabkan oleh perubahan pada workload serta peningkatan traffic.

Dependensi non-penskalaan

Jika dependensi Anda tidak bertambah seiring peningkatan jumlah instance App Engine, dependensi tersebut mungkin akan mengalami overload saat traffic meningkat. Contoh dependensi yang tidak dapat diskalakan adalah database SQL. Jumlah instance aplikasi yang lebih tinggi akan menghasilkan jumlah koneksi database yang lebih tinggi. Hal ini dapat menyebabkan kegagalan beruntun karena database tidak dapat dimulai.

Salah satu cara untuk memulihkan kondisi ini adalah sebagai berikut:

  1. Men-deploy versi default baru yang tidak terhubung ke database.
  2. Menonaktifkan versi default sebelumnya.
  3. Men-deploy versi non-default baru yang terhubung ke database.
  4. Memigrasikan traffic ke versi baru secara perlahan.

Salah satu tindakan pencegahan potensial adalah mendesain aplikasi agar melepaskan permintaan ke dependensi menggunakan Throttling Adaptif.

Kegagalan lapisan cache

Cara yang baik untuk mempercepat permintaan adalah dengan memanfaatkan beberapa lapisan cache:

  • Edge caching
  • Memcache
  • Memori dalam instance

Peningkatan latensi mendadak dapat disebabkan oleh kegagalan di salah satu lapisan cache ini. Misalnya, flush Memcache dapat menyebabkan lebih banyak permintaan menuju ke Datastore yang lebih lambat.