Konteks dan cakupan
Sebuah API Node.js menunjukkan lonjakan latensi P99 selama lonjakan traffic, sementara latensi database dan layanan eksternal tidak meningkat pada waktu yang sama. Rancang diagnosis yang membedakan event loop yang terblokir dari dependensi yang lambat. Runtime yang digunakan adalah Node.js 26.5.0; API monitorEventLoopDelay miliknya menambahkan samplePerIteration, yang mengambil sampel satu kali per iterasi event-loop sambil tetap mempertahankan sampling berbasis interval.
Jelaskan semantik sampling, unit nanodetik, masa pakai (lifetime) histogram, perilaku proses idle, dan mengapa metrik observasi tidak boleh disalahartikan sebagai latensi request.
Hal yang dievaluasi oleh pewawancara
Pewawancara mencari definisi yang tepat tentang apa yang diukur oleh loop delay sebelum memilih suatu mode. Jawaban yang kuat menjelaskan bahwa histogram harus diaktifkan, dibaca, dan dinonaktifkan, dengan window yang selaras dengan metrik request. Jawaban tersebut juga harus mengenali bahwa mengubah mode sampling akan mengubah distribusi sampel, sehingga nilai P99 dari mode yang berbeda tidak dapat dibandingkan secara langsung.
Jawaban terbaik mengorelasikan loop delay dengan CPU, garbage collection (GC), antrean (queueing), latensi downstream, dan beban instance. Jawaban tersebut mengusulkan pemantauan steady-state berbiaya rendah, diagnostic window beresolusi tinggi yang singkat, serta perbandingan rollback plus kontrol.
Pertanyaan klarifikasi sebelum menjawab
- Apakah kita mencari sumber pemblokiran lokal atau menjelaskan P99 end-to-end secara langsung?
- Apakah ini proses jangka panjang (long-lived), instance serverless, atau CLI jangka pendek?
- Berapa diagnostic window, resolusi sampling, dan overhead pemantauan yang dapat diterima?
- Apakah semua instance menggunakan Node.js 26.5.0, atau versinya bervariasi?
- Apakah kita juga memiliki metrik CPU, GC, antrean request, latensi dependensi, dan utilisasi event-loop?
Kerangka jawaban 30 detik
“Saya akan mendefinisikan event-loop delay sebagai waktu di mana progres loop teramati lebih lambat dari yang diharapkan, bukan sebagai latensi request. Node.js melaporkan nilai histogram dalam nanodetik. Saya akan menggunakan interval sampling untuk pemantauan steady-state dan mengevaluasi per-iteration sampling hanya untuk diagnostic window yang singkat. Kedua mode memiliki mekanisme pembuatan sampel yang berbeda, sehingga persentilnya memerlukan baseline terpisah. Saya akan memulai dan menghentikan histogram untuk window tertentu, mencatat P50, P99, maksimum, dan jumlah sampel, serta mengorelasikannya dengan CPU, GC, latensi dependensi, dan P99 request. Jika hanya loop delay yang meningkat, saya akan menyelidiki synchronous CPU work, system call, dan stack trace.”
Jawaban mendalam langkah demi langkah
Tentukan batasan metrik
monitorEventLoopDelay mengembalikan histogram delay dalam nanodetik. Ini mendeskripsikan delay yang teramati dalam progres event-loop pada titik sampling; ini tidak mencakup siklus hidup jaringan penuh dari suatu request dan tidak dapat mengidentifikasi pemblokir secara mandiri. Untuk menjelaskan P99 yang terlihat oleh pengguna, selaraskan dengan waktu mulai request, antrean, pekerjaan aplikasi, dan downstream dalam window yang sama.
Memilih di antara mode sampling
Mode default mengambil sampel berdasarkan timer yang dikendalikan oleh resolution, yang cocok untuk pemantauan steady-state berbiaya rendah. Node.js 26.5.0 menambahkan samplePerIteration: true, yang mengambil sampel satu kali per iterasi loop. Dokumentasi juga menyatakan bahwa mode ini tidak memaksakan iterasi ekstra atau membuat loop tetap aktif saat proses sedang idle.
Per-iteration sampling berguna untuk episode pemblokiran singkat ketika instance memiliki aktivitas loop yang berkelanjutan. Mode ini menghasilkan jumlah dan distribusi sampel yang berbeda, sehingga P99 dari satu mode tidak dapat digunakan sebagai hasil regresi terhadap P99 dari mode lainnya.
Mengelola masa pakai histogram
Perlakukan histogram sebagai window state, bukan sebagai akumulator global permanen. Buat dan lakukan enable() di awal diagnostic window, baca percentile(99), max, dan count di akhir, lalu lakukan disable() dan ekspor atau buang snapshot tersebut. Nama metrik harus menyertakan mode sampling, resolusi, versi Node, dan batasan window.
import { monitorEventLoopDelay } from 'node:perf_hooks';
const histogram = monitorEventLoopDelay({
resolution: 20,
samplePerIteration: true,
});
histogram.enable();
setTimeout(() => {
const snapshot = {
p99Ns: histogram.percentile(99),
maxNs: histogram.max,
samples: histogram.count,
};
histogram.disable();
console.log(snapshot);
}, 10_000);Konversi unit pada batas sistem
Nilai histogram dalam satuan nanodetik. Bagi dengan 1_000_000 untuk milidetik sambil tetap mempertahankan nilai mentah untuk perbandingan yang tepat. Jangan memperlakukan nilai maksimum sebagai SLA; satu outlier dapat berasal dari pause, proses yang membeku (freeze), atau batas pengukuran. Lebih utamakan P99, P999, maksimum, jumlah sampel, dan deret waktu (time series) pada window yang tetap.
Korelasikan pemblokir yang memungkinkan
Jika loop delay dan CPU meningkat bersamaan, periksa serialisasi JSON sinkron, operasi regular expression yang katastropik, kompresi, enkripsi, dan penelusuran array besar. Jika GC meningkat bersamanya, periksa pertumbuhan heap dan laju alokasi. Jika loop delay tinggi sementara CPU rendah, selidiki synchronous system call, lock wait, atau penjadwalan host. Jika hanya latensi dependensi dan P99 request yang meningkat, metrik loop lokal tidak dapat menggantikan pelacakan dependensi.
Menangani versi campuran dan overhead
Catat versi runtime saat startup dan pisahkan metrik berdasarkan versi. Instance yang lebih lama dari 26.5.0 tidak memiliki samplePerIteration; jangan menganggap opsi tersebut tersedia begitu saja. Gunakan resolution yang lebih besar untuk pemantauan steady-state dan feature flag untuk window per-iteration yang singkat selama insiden. Sampling frekuensi tinggi secara terus-menerus menambah biaya observasi dan mempersulit perbandingan lintas versi.
Verifikasi dan rollback
Buat sampel terkontrol dengan pemblokiran CPU sinkron, pemblokiran timer, tekanan GC, dan proses idle. Verifikasi konversi unit, perilaku enable/disable yang bersih, tidak ada wake-up buatan saat idle, dan keselarasan dengan P99 request saat terjadi gangguan. Jika biaya sampling atau noise memengaruhi layanan, nonaktifkan flag diagnostik dan kembali ke interval sampling; pertahankan sampel kontrol yang diberi label versi dan mode.
Jawaban model berkualitas tinggi
“Saya akan memperlakukan monitorEventLoopDelay sebagai sinyal kesehatan penjadwalan lokal, bukan sebagai latensi request. Saya akan menggunakan resolution untuk sampling steady-state yang murah dan mengaktifkan per-iteration sampling Node.js 26.5.0 hanya dalam diagnostic window yang singkat untuk pemblokiran singkat. Setiap window membuat, mengaktifkan, membaca, dan menonaktifkan satu histogram, dan nanodetik dikonversi secara konsisten ke milidetik. Saya akan menyelaraskan P99 dengan CPU, GC, latensi dependensi, dan P99 request; hanya peningkatan lokal yang terjadi bersamaan yang akan mengarahkan penyelidikan saya ke synchronous CPU, system call, atau penjadwalan. Kedua mode memerlukan baseline terpisah, dan versi runtime yang beragam harus dipisahkan.”
Kesalahan umum
- Memperlakukan loop delay sebagai latensi request → waktu downstream dan antrean tetap tidak terlihat → tentukan lapisan (layer) dan selaraskan dengan pelacakan request.
- Melupakan nanodetik → laporan meleset hingga faktor satu juta → konversikan pada batasan dan pertahankan nilai mentah.
- Membandingkan P99 lintas mode → mekanisme pembuatan sampel berbeda → buat baseline khusus untuk setiap mode.
- Membiarkan per-iteration sampling aktif selamanya → biaya dan noise terus berlanjut → ambil sampel dengan biaya rendah secara normal dan intensifkan secara singkat selama insiden.
- Mengabaikan perilaku idle → operator salah mengartikan apakah sampling memicu aktivitas instance → uji proses idle secara eksplisit.
- Menggabungkan versi runtime → instance yang lebih lama tidak memiliki opsi ini → beri tag dan agregasikan berdasarkan versi.
Pertanyaan lanjutan dan tanggapan
Pertanyaan lanjutan 1: Apakah P99 per-iteration yang lebih tinggi membuktikan adanya regresi performa?
Tidak. Titik observasi, jumlah sampel, dan distribusinya telah berubah. Jalankan kedua mode di bawah beban, versi, dan window yang sama, bandingkan masing-masing dengan baseline-nya sendiri, serta bandingkan CPU, throughput, dan P99 request saat mengukur overhead pemantauan.
Pertanyaan lanjutan 2: Mengapa loop delay bisa tinggi sementara CPU rendah?
Synchronous system call, lock wait, penjadwalan host, atau jeda proses dapat menunda progres tanpa penggunaan CPU user-space yang tinggi. Gabungkan diagnostik runtime, metrik sistem, dan stack trace daripada menyimpulkan bahwa tidak ada pemblokiran.
Pertanyaan lanjutan 3: Haruskah fungsi serverless membiarkan histogram ini aktif secara permanen?
Biasanya tidak sebagai sinyal utama lintas request: masa pakai instance pendek dan window mungkin terpotong. Build diagnostik dapat mengambil sampel per pemanggilan (invocation) atau untuk batch pendek sambil mencatat cold start, waktu eksekusi, dan trace downstream.
Pertanyaan lanjutan 4: Bagaimana Anda membuktikan bahwa sampling tidak mengubah perilaku idle?
Jalankan proses tanpa timer atau request di bawah masing-masing mode. Amati perilaku keluar (exit), jumlah iterasi loop, dan CPU. Mode per-iteration tidak boleh memaksakan iterasi ekstra untuk sampling atau membuat loop tetap aktif.