Metode Mendiagnosis dan Memecahkan Masalah Lonjakan CPU pada Aplikasi Java
Metode Mendiagnosis dan Memecahkan Masalah Lonjakan CPU pada Aplikasi Java
[ad_1]
Salah satu masalah performa paling umum yang dialami oleh aplikasi Java adalah lonjakan performa CPU. Meskipun alat Manajemen Kinerja Aplikasi (APM) tradisional memberikan wawasan tingkat tinggi tentang penggunaan CPU secara keseluruhan, alat tersebut sering kali gagal mengidentifikasi akar penyebab lonjakan tersebut. Alat APM biasanya tidak dapat mengidentifikasi jalur kode pasti yang menyebabkan masalah. Itu di sini tidak menggangguanalisis tingkat thread jauh lebih efisien. Dalam artikel ini, saya akan membagikan beberapa metode praktis untuk membantu Anda mendiagnosis dan mengatasi lonjakan CPU tanpa membuat perubahan apa pun pada lingkungan produksi Anda.
Pendekatan intrusif atau non-intrusif: apa bedanya?
Pendekatan yang mengganggu
Pendekatan intrusif melibatkan perubahan pada kode atau konfigurasi aplikasi, seperti mengaktifkan pembuatan profil terperinci, menambahkan logging tambahan, atau melampirkan agen pemantauan kinerja. Metode ini dapat memberikan data terperinci, namun dapat memengaruhi kinerja aplikasi dan mungkin tidak cocok untuk lingkungan produksi karena adanya overhead tambahan.
Pendekatan non-intrusif
Sebaliknya, pendekatan non-intrusif tidak memerlukan modifikasi apa pun pada aplikasi yang sedang berjalan. Mereka mengandalkan pengumpulan data eksternal seperti thread dump, penggunaan CPU, dan log tanpa mengganggu pengoperasian normal aplikasi. Metode ini lebih aman untuk lingkungan produksi karena menghindari potensi penurunan kinerja dan memungkinkan Anda memecahkan masalah aplikasi langsung tanpa gangguan.
1. atas -H + Pembuangan Benang
Konsumsi CPU yang tinggi selalu disebabkan oleh thread yang terus menerus menerapkan kode. Aplikasi kita cenderung berisi ratusan (terkadang ribuan) thread. Langkah pertama dalam diagnosis adalah mengidentifikasi thread yang memakan CPU di antara ratusan thread ini.
Cara sederhana dan efektif untuk melakukan ini adalah dengan menggunakan top
memesan. ITU top
Perintah ini adalah utilitas yang tersedia di semua versi sistem Unix yang menyediakan tampilan real-time penggunaan sumber daya sistem, termasuk konsumsi CPU oleh setiap thread dalam proses tertentu. Anda dapat mengeluarkan yang berikut ini top
perintah untuk mengidentifikasi thread yang paling banyak memakan CPU:
top -H -p
Perintah ini mencantumkan masing-masing thread dalam proses Java dan konsumsi CPU masing-masing, seperti yang ditunjukkan pada Gambar 1 di bawah:
Gambar 1: atas -H -p
Setelah Anda mengidentifikasi thread yang intensif CPU, langkah berikutnya adalah menentukan baris kode mana yang dieksekusi oleh thread tersebut. Untuk melakukan ini, Anda perlu mengambil dump thread dari aplikasi, yang akan menampilkan jalur eksekusi kode thread ini. Namun, ada beberapa hal yang perlu diingat:
- Anda harus mengeluarkan
top -H -p
perintah dan tangkap dump thread secara bersamaan untuk mengetahui baris kode yang tepat yang menyebabkan lonjakan CPU. Lonjakan CPU bersifat sementara, jadi menangkap keduanya secara bersamaan memastikan bahwa Anda dapat menghubungkan penggunaan CPU yang tinggi dengan kode persis yang sedang dieksekusi. Keterlambatan apa pun di antara keduanya dapat mengakibatkan akar permasalahan terabaikan. - ITU
top -H -p
Perintah ini mencetak ID thread dalam format desimal, tetapi di dump thread, ID thread dalam format heksadesimal. Anda perlu mengonversi ID thread desimal menjadi heksadesimal untuk menemukannya di dump.
Ini adalah metode paling efektif dan akurat untuk mengatasi masalah lonjakan CPU. Namun, di beberapa lingkungan, termasuk lingkungan dalam container, perintah teratas mungkin tidak diinstal. Dalam kasus seperti itu, Anda mungkin ingin menjelajahi metode alternatif yang disebutkan di bawah.
2. Thread status yang dapat dijalankan di beberapa dump
Utas Java dapat berada di beberapa negara bagian: NEW
, RUNNABLE
, BLOCKED
, WAITING
, TIMED_WAITING
Atau TERMINATED
. Jika Anda tertarik, Anda dapat mempelajari berbagai status thread. Ketika sebuah thread secara aktif mengeksekusi kode, maka thread tersebut akan berada di RUNNABLE
Negara. Lonjakan CPU selalu disebabkan oleh thread di RUNNABLE
Negara. Untuk mendiagnosis puncak ini secara efektif:
- Tangkap 3-5 thread dump dengan interval 10 detik.
- Identifikasi rangkaian diskusi yang secara konsisten tetap ada di
RUNNABLE
kondisi di semua tempat pembuangan sampah. - Analisis jejak tumpukan thread ini untuk menentukan bagian kode mana yang menggunakan CPU.
Meskipun analisis ini dapat dilakukan secara manual, alat analisis thread dump seperti fastThread mengotomatiskan prosesnya. fastThread menghasilkan bagian “CPU Spike” yang menyoroti thread yang terus-menerus berada di RUNNABLE
status di beberapa dump. Namun, metode ini tidak akan menunjukkan persentase pasti penggunaan CPU oleh setiap thread.
Kekurangan
Metode ini akan menampilkan semua thread dari RUNNABLE
negara, terlepas dari konsumsi CPU sebenarnya. Misalnya, thread yang menggunakan 80% CPU dan thread yang hanya menggunakan 5% akan keduanya muncul. Ini tidak akan memberikan konsumsi CPU yang tepat untuk masing-masing thread, jadi Anda mungkin perlu menyimpulkan tingkat keparahan lonjakan, berdasarkan perilaku thread dan pola eksekusi.
3. Menganalisis thread status RUNNABLE dari satu dump
Terkadang Anda hanya memiliki satu snapshot dari thread dump. Dalam kasus seperti ini, pendekatan membandingkan beberapa dump tidak dapat diterapkan. Namun, Anda masih dapat mencoba mendiagnosis lonjakan CPU dengan berfokus pada thread server. RUNNABLE
Negara. Satu hal yang perlu diperhatikan adalah JVM mengklasifikasikan semua thread yang menjalankan metode asli sebagai RUNNABLE
tetapi banyak metode asli (seperti java.net.SocketInputStream.socketRead0()
) jangan jalankan kode apa pun dan tunggu saja operasi I/O.
Agar tidak disesatkan oleh topik-topik seperti itu, Anda perlu menyaring hal-hal positif palsu ini dan fokus pada hasil nyata. RUNNABLE
putra negara. Proses ini mungkin membosankan, tetapi fastThread mengotomatiskannya dengan memfilter thread yang menyesatkan ini di bagian “Thread yang Memakan CPU”, sehingga Anda dapat fokus pada penyebab sebenarnya di balik lonjakan CPU.
Kekurangan
Metode ini memiliki beberapa kelemahan:
- Thread diskusi mungkin sementara ada di
RUNNABLE
negara bagian tetapi dapat dengan cepat pindah keWAITING
AtauTIMED_WAITING
(yaitu negara yang tidak menggunakan CPU). Dalam kasus seperti ini, mengandalkan satu snapshot dapat menghasilkan kesimpulan yang menyesatkan tentang dampak thread terhadap konsumsi CPU. - Mirip dengan metode #2, ini akan menampilkan semua thread dari
RUNNABLE
negara, terlepas dari konsumsi CPU sebenarnya. Misalnya, thread yang menggunakan 80% CPU dan thread yang hanya menggunakan 5% akan keduanya muncul. Ini tidak akan memberikan konsumsi CPU yang tepat untuk masing-masing thread, jadi Anda mungkin perlu menyimpulkan tingkat keparahan lonjakan, berdasarkan perilaku thread dan pola eksekusi.
Studi Kasus: Mendiagnosis Lonjakan CPU pada Aplikasi Perdagangan Utama
Dalam satu kasus, aplikasi perdagangan besar mengalami lonjakan CPU yang parah, yang secara signifikan memengaruhi kinerjanya selama jam-jam perdagangan penting. Dengan menangkap thread dump dan menerapkan metode #1 yang dijelaskan di atas, kami mengidentifikasi bahwa penyebab utama adalah penggunaan struktur data yang tidak aman untuk thread. Beberapa thread secara bersamaan mengakses dan memodifikasi struktur data ini, menyebabkan konsumsi CPU yang berlebihan. Setelah masalah teridentifikasi, tim pengembangan mengganti struktur data non-thread-safe dengan alternatif thread-safe, yang menghilangkan konflik dan mengurangi penggunaan CPU secara signifikan. Untuk rincian lebih lanjut tentang studi kasus ini, baca terus Di Sini.
Kesimpulan
Mendiagnosis lonjakan CPU pada aplikasi Java bisa jadi sulit, terutama jika alat APM tradisional tidak cukup. Dengan menggunakan metode non-intrusif seperti menganalisis thread dump dan memfokuskannya RUNNABLE
utas status, Anda dapat mengidentifikasi penyebab pasti lonjakan CPU.
[ad_2]