Rumah > Artikel > hujung hadapan web > [Ringkasan Pengalaman] Bagaimana untuk menyelesaikan masalah kebocoran memori dalam Node? Berkongsi idea
Bagaimana untuk menyelesaikan masalah kebocoran memori dalam Node? Artikel berikut akan meringkaskan pengalaman penyelesaian masalah kebocoran memori Node untuk semua orang.
Dalam senario Nodejs
pembangunan sisi pelayan, 内存泄漏
pastinya merupakan masalah yang paling menyusahkan;
Tetapi selagi projek itu terus dibangunkan dan diulang, masalah 内存泄漏
sememangnya tidak dapat dielakkan, ia hanya berlaku lambat laun. Oleh itu, menguasai kaedah penyelesaian masalah 内存泄漏
yang berkesan secara sistematik adalah keupayaan paling asas dan teras seorang jurutera Nodejs
.
Kesukaran menangani kebocoran ingatan ialah bagaimana untuk mengetahui antara fungsi dan fungsi yang tidak terkira dengan tepat yang mana fungsi dan baris mana dalam fungsi yang menyebabkan kebocoran memori.
Malangnya, pada masa ini tiada alat di pasaran yang boleh mengesan kebocoran memori dengan mudah, jadi ramai jurutera yang menghadapi masalah ini buat kali pertama akan berasa keliru dan tidak tahu bagaimana untuk menanganinya.
Di sini saya akan berkongsi idea pemprosesan saya berdasarkan kes siasatan 内存泄漏
dalam tempoh 22 tahun.
2022 Q4
Pada suatu hari, kumpulan pengguna R&D melaporkan bahawa platform R&D kami tidak dapat diakses, dan terdapat sejumlah besar tugas yang tidak normal dalam latar belakang yang tidak disiapkan.
Reaksi pertama ialah mungkin terdapat kebocoran memori Nasib baik, perkhidmatan disambungkan ke pemantauan (prometheus
+ grafana
Dalam panel pemantauan grafana
, didapati bahawa memori telah meningkat sejak 10.00 dan). belum turun. Terdapat kebocoran data yang jelas. [Cadangan tutorial berkaitan: tutorial video nodejs]
Arahan:
process memory
:rss
(Saiz Set Penduduk), saiz memori pemastautin proses.heapTotal
: Jumlah saiz timbunan V8.heapUsed
: Saiz timbunan V8 yang digunakan.external
: Penggunaan memori luar timbunan V8.Anda boleh memanggil kaedah global
Nodejs
dalamprocess.memoryUsage()
untuk mendapatkan data ini danheapTotal
ialah penggunaan timbunan V8, dan timbunan V8 disimpan oleh objek JavaScript. di tempatheapUsed
. DanNode.js
mewakili memori yang diperuntukkan dalam timbunan bukan V8, seperti objek C++.external
ialah jumlah penggunaan memori bagi proses tersebut. Secara amnya apabila melihat data pemantauan, hanya fokus pada penunjukrss
heapUsed
Malah, sama ada kebocoran memori global atau kebocoran memori tempatan, apa yang perlu kita lakukan ialah untuk meminimumkannya sebanyak mungkin Julat pengecualian.
dan 中间件
Penyelesaian masalah kebocoran memori jenis ini Ia juga paling mudah untuk dilakukan bangun. 组件
bukan tergolong dalam jenis ini, jadi saya perlu menganalisisnya mengikut idea kebocoran tempatan. 2022 Q4
Aliran proses:
, 中间件
atau perkara biasa lain logik separuh) 组件
Pada tahun 2020, semasa saya sedang mengusahakan aplikasi SSR berdasarkan, saya mendapati kebocoran memori aplikasi semasa ujian tekanan sebelum pergi dalam talian. Selepas menentukan ia sebagai kebocoran global, ia mengambil masa kira-kira 30 minit untuk menggunakan kaedah dikotomi untuk menyelesaikan masalah tersebut.
Nuxt
Sebab kebocoran pada masa itu adalah kerana kami menggunakan
di bahagian pelayan Kemudian, ia diselesaikan selepas menyatukan semuaaxios
perkara yang berkaitan dan menggantikannya denganaxios
Sejak itu, kami menggantikan mereka dengannode-fetch
dan mereka tidak akan digunakan lagi kemudianaxios PDST
GunakanNode
dalam perkhidmatanaxios
tertentu, 中间件
tertentu atau 接口
tertentu Disebabkan ciri ini, ia lebih sukar untuk diselesaikan. Dalam kes ini, 异步任务
akan digunakan untuk analisis. heapdump
Di sini saya bercakap tentang idea saya dalam kes ini, saya akan meletakkan penerangan terperinci heapdump
dalam perenggan seterusnya,
Heap Dump
: Longgokan longgokan, bahagian berikut dinyatakan. olehheapdump
, terdapat banyak alatan dan tutorial untuk melakukanheapdump
, seperti: chrome, vscode, heapdump, perpustakaan sumber terbuka ini. Terdapat banyak tutorial dalam talian untuk perpustakaan heapdump yang saya gunakan, yang saya tidak akan pergi ke sini.
Menyelesaikan masalah kebocoran memori setempat memerlukan sejumlah pengalaman penyelesaian masalah kebocoran memori Setiap kali anda menghadapinya, anggap ia sebagai ujian untuk diri sendiri Selepas anda mengumpul lebih banyak pengalaman, anda boleh menyelesaikan masalah memori masalah kebocoran nanti.
Ini sangat penting dengan mengetahui perkara ini boleh mengecilkan skop penyiasatan.
Situasi ini sering berlaku Lelaran ini mempunyai tiga fungsi A, B dan C, dan kebocoran memori berlaku semasa ujian tekanan atau selepas pergi ke dalam talian. Kemudian anda boleh terus mengunci dan kebocoran memori kecil akan berlaku di antara tiga fungsi baharu ini. Dalam kes ini, tidak perlu pergi ke pengeluaran heapdump
Kami boleh menganalisis dan mencari titik kebocoran memori secara tempatan melalui beberapa alatan.
Disebabkan beberapa keadaan istimewa 20年Q4
kami, apabila kami menemui kebocoran memori, sukar untuk menentukan bila kebocoran ingatan mula-mula muncul. Kami hanya boleh menguncinya secara kasar pada bulan Januari. Bulan ini kami telah melalui satu lagi lelaran versi utama Jika kami menyemak fungsi dan antara muka ini satu demi satu, kosnya akan menjadi sangat tinggi.
Oleh itu, lebih banyak data perlu digabungkan untuk analisis selanjutnya
node
Tambahkan --expose-gc
, parameter ini. Kaedah gc()
akan disuntik secara global untuk memudahkan pencetus manual GC untuk mendapatkan data 堆快照
yang lebih tepat heapdump
Pengumpulan Terdapat beberapa perkara yang memerlukan perhatian khusus apabila menimbun data syot kilat!
- Perkhidmatan Node akan terganggu pada
heapdump
Masa ini akan mengambil masa kira-kira 2 hingga 30 minit bergantung pada saiz memori pelayan pada masa itu. Untuk melakukanheapdump
dalam persekitaran pengeluaran, anda perlu bekerja dengan operasi dan penyelenggaraan untuk merangka strategi yang munasabah. Saya menggunakan duapod
rendah dan menengah di sini Apabilapod
utama dihentikan, permintaan perniagaan akan dimuatkan seimbang kepadapod
menengah untuk memastikan kemajuan biasa perniagaan pengeluaran. (Proses ini mestilah proses yang diselaraskan rapat dengan operasi dan penyelenggaraan. Lagipun,heapdump
anda masih perlu mendapatkan堆快照
fail dalam pelayan melaluinya)- Syot kilat pencetakan yang disebutkan di atas berhampiran titik kritikal hanyalah penerangan yang tidak jelas, jika anda telah mencubanya, anda akan tahu bahawa jika anda menunggu sangat dekat dengan titik kritikal sebelum mencetak gambar memori, anda tidak akan dapat mencetaknya. Jadi anda perlu mengawal diri anda untuk mendekati ijazah ini.
- Lakukan sekurang-kurangnya 3 kali
heapdump
(sebenarnya saya melakukannya 5 kali untuk mendapatkan data yang paling terperinci)
memerlukan perkhidmatan aplikasi anda untuk mengakses pemantauan Aplikasi di sini menggunakan prometheus
+ grafana
untuk pemantauan terutamanya penunjuk perkhidmatan berikut
QPS
(minta lawatan sesaat), status permintaan dan laluan aksesnya ART
(purata masa tindak balas antara muka) dan data aksesnya NodeJs
versi Actice Handlers
(pegangan)Event Loop Lag
(selang peristiwa)rss
, heapTotal
, heapUsed
, external
, heapAvailableDetail
Hanya
heapdump
data tidak mencukupi,heapdump
data sangat kabur , Walaupun dengan sokongan alat visualisasi, sukar untuk mengesan masalah dengan tepat. Pada masa ini, saya melihatnya bersama-sama dengan beberapa data daripadagrafana
.
Memandangkan data syot kilat pada masa itu hilang, saya akan mensimulasikan pemandangan di sini.
1. Melalui antara muka pemantauan grafana
, saya mendapati bahawa memori telah meningkat dan tidak berkurangan, tetapi pada masa yang sama, saya juga menyedari bahawa bilangan 句柄
dalam perkhidmatan telah juga melambung tinggi dan tidak turun.
2. Ini adalah semasa saya menyemak ciri baharu pada bulan kebocoran berlaku dan mengesyaki bahawa kebocoran memori mungkin disebabkan oleh penggunaan komponen baris gilir mesej bull
. Saya mula-mula menganalisis kod aplikasi yang berkaitan, tetapi saya tidak dapat melihat bahawa terdapat sesuatu yang tidak kena dengannya yang menyebabkan kebocoran memori.
Digabungkan dengan masalah kebocoran pemegang dalam 1, nampaknya anda perlu mengeluarkan sumber tertentu secara manual selepas menggunakan bull
Pada masa ini, saya tidak pasti tentang sebab tertentu.
3. Kemudian 5 kali data heapdunmp
dianalisis, dan data diimport chrome
Selepas membandingkan 5 kali syot kilat timbunan, didapati tiada peristiwa untuk TCP, Socket, dan EventEmitter selepas setiap baris gilir dilepaskan ke. Pada ketika ini, pada asasnya pasti ia berpunca daripada penggunaan bull
yang tidak teratur. Barisan gilir biasanya tidak dibuat dengan kerap dalam bull
dan sumber sistem yang diduduki oleh baris gilir tidak dikeluarkan secara automatik Jika perlu, ia perlu dikeluarkan secara manual.
4. Selepas melaraskan kod, ujian tekanan dilakukan semula dan masalah telah diselesaikan.
Petua:
句柄
dalam Nodejs ialah penunjuk yang menunjuk kepada sumber sistem asas (seperti fail, sambungan rangkaian, dll.). Pemegang membenarkan program Node.js mengakses dan memanipulasi sumber ini tanpa berinteraksi secara langsung dengan sistem asas. Pemegang boleh menjadi integer atau objek, bergantung pada jenis pemegang yang digunakan oleh perpustakaan atau modul Node.js. Biasa句柄
:
fs.open()
Pemegang fail yang dikembalikannet.createServer()
Pemegang pelayan rangkaian yang dikembalikandgram.createSocket()
Pemegang soket UDP yang dikembalikanchild_process.spawn()
Mengembalikan pemegang proses anakcrypto.createHash()
Mengembalikan pemegang cincangzlib.createGzip()
Mengembalikan pemegang mampatan
Biasanya ramai yang keliru apabila mendapat data 堆快照
buat kali pertama, dan saya juga begitu. Selepas membaca banyak teknik analisis di Internet dan menggabungkannya dengan amalan sebenar saya sendiri, saya telah merumuskan beberapa teknik yang lebih berguna Beberapa tutorial penggunaan asas tidak akan dibincangkan di sini. Di sini kita bercakap tentang cara melihat gambar selepas data diimport chrome
;
Apabila melihat paparan ini, Retained Saiz biasanya akan diperiksa dahulu Kemudian perhatikan saiz dan bilangan objek Jurutera yang berpengalaman boleh dengan cepat menentukan bilangan objek tertentu adalah tidak normal. Dalam pandangan ini, selain mengambil berat tentang beberapa objek yang ditentukan oleh anda sendiri, Sesetengah objek yang terdedah kepada kebocoran ingatan juga memerlukan perhatian, seperti:
TCP
Socket
EventEmitter
global
Jika masalah tidak dapat dikesan melalui paparan Summary
, maka biasanya kami menggunakan paparan Comparison
. Melalui pandangan ini, kita boleh membandingkan bilangan objek dalam dua petikan timbunan dan perubahan dalam memori yang diduduki oleh objek;
Melalui maklumat ini, kita boleh menilai nilai objek dalam timbunan dan perubahan memori selepas tempoh masa (operasi tertentu, melalui nilai ini, kita boleh menemui beberapa objek yang tidak normal). Nama atribut atau fungsi objek ini boleh mengecilkan skop penyiasatan kebocoran ingatan kami.
Pilih dua petikan timbunan dalam paparan Comparison
dan bandingkan antaranya. Anda boleh melihat objek mana yang telah ditambah antara dua syot kilat timbunan, objek mana yang dikecilkan antara dua syot kilat timbunan dan objek mana yang berubah dalam saiz. Comparison
Paparan juga membenarkan melihat perhubungan antara objek, serta butiran objek seperti jenis, saiz dan kiraan rujukan. Dengan maklumat ini, anda boleh memahami objek mana yang menyebabkan kebocoran memori.
memaparkan semua hubungan rujukan yang boleh dicapai antara objek. Setiap objek diwakili sebagai titik dan disambungkan kepada objek induknya dengan garis. Dengan cara ini anda boleh melihat perhubungan hierarki antara objek dan memahami objek yang menyebabkan kebocoran memori.
Gambar ini sangat mudah dan saya tidak akan menerangkan secara terperinci
lru-cache
dan bukannya redis
lru-cache
Lain-lainAlat Ujian Tekanan: wrk
堆快照
Atas ialah kandungan terperinci [Ringkasan Pengalaman] Bagaimana untuk menyelesaikan masalah kebocoran memori dalam Node? Berkongsi idea. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!