Cara cepat memulai VUE3.0: Masuk ke pembelajaran.
Setelah layanan kami dirilis, pasti akan dijadwalkan oleh lingkungan yang sedang berjalan (seperti container, pm2, dll.), peningkatan layanan akan menyebabkan restart, dan berbagai pengecualian akan menyebabkan proses terhenti; secara umum, lingkungan yang berjalan memiliki Pemantauan kesehatan dari proses layanan akan memulai kembali proses ketika proses tidak normal. Saat melakukan peningkatan, ada juga strategi peningkatan bergulir. Namun, strategi penjadwalan lingkungan yang berjalan memperlakukan proses layanan kami sebagai kotak hitam dan tidak peduli dengan kondisi internal proses layanan yang berjalan, oleh karena itu, proses layanan kami perlu secara aktif merasakan tindakan penjadwalan dari lingkungan yang berjalan dan kemudian melakukan beberapa tindakan pembersihan keluar.
Jadi hari ini kita akan memilah berbagai situasi yang mungkin menyebabkan proses keluarnya Node.js, dan apa yang dapat kita lakukan dengan mendengarkan peristiwa keluarnya proses ini.
Prinsip:
Ketika suatu proses ingin keluar, tidak lebih dari dua situasi: Yang pertama adalah proses keluar secara aktif, dan yang lainnya adalah proses menerima sinyal sistem yang memerlukan proses untuk keluar.
Keluar dari pemberitahuan sinyal sistem
Sinyal sistem umum tercantum dalam dokumen resmi Node.js. Kami terutama fokus pada beberapa hal:
Saat menerima sinyal keluar yang tidak dipaksakan, proses Node.js dapat mendengarkan sinyal keluar dan melakukan beberapa logika keluar khusus. Misalnya, kami menulis alat cli yang membutuhkan waktu lama untuk menjalankan suatu tugas. Jika pengguna ingin keluar dari proses melalui ctrl+c sebelum tugas selesai, pengguna dapat diminta untuk menunggu:
const readline = require(' garis baca'); proses.pada('SIGINT', () => { // Kami menggunakan readline untuk sekadar mengimplementasikan interaksi di baris perintah const rl = readline.createInterface({ masukan: proses.stdin, keluaran: proses.stdout }); rl.question('Tugas belum selesai, apakah Anda yakin ingin keluar?', jawab => { jika (jawaban === 'ya') { console.log('Eksekusi tugas terhenti, keluar dari proses'); proses.keluar(0); } kalau tidak { console.log('Tugas berlanjut...'); } rl.tutup(); }); }); // Simulasikan tugas yang memerlukan waktu 1 menit untuk dieksekusi const longTimeTask = () => { console.log('tugas dimulai...'); setWaktu habis(() => { console.log('tugas berakhir'); }, 1000*60); }; longTimeTask();
Efeknya adalah sebagai berikut.
Proses keluar secara aktif dari
Node.js. Proses keluar secara aktif, terutama mencakup situasi berikut:
Kita tahu bahwa pm2 memiliki efek proses daemon. Ketika proses Anda keluar dengan kesalahan, pm2 akan memulai kembali proses Anda proses anak dalam mode cluster Node.js (sebenarnya pm2 memiliki logika serupa):
const cluster = require('cluster' ); const http = memerlukan('http'); const numCPUs = memerlukan('os').cpus().panjang; const proses = memerlukan('proses'); //Kode proses utama if (cluster.isMaster) { console.log(`Mulai proses utama: ${process.pid}`); // Berdasarkan jumlah inti cpu, buat proses kerja untuk (misalkan i = 0; i < numCPUs; i++) { cluster.fork(); } //Dengarkan cluster kejadian keluar proses pekerja.on('exit', (pekerja, kode, sinyal) => { console.log(`Proses pekerja ${worker.process.pid} keluar, kode kesalahan: ${code || signal}, memulai ulang...`); //Mulai ulang proses anak cluster.fork(); }); } // Kode proses pekerja if (cluster.isWorker) { // Dengarkan kejadian kesalahan yang tidak tertangkap process.on('uncaughtException', error => { console.log(`Terjadi kesalahan dalam proses pekerja ${process.pid}`, error); proses.memancarkan('putuskan'); proses.keluar(1); }); //Buat server web // Setiap proses pekerja akan mendengarkan port 8000 (Node.js akan menanganinya secara internal dan tidak akan menyebabkan konflik port) http.createServer((permintaan, res) => { res.writeHead(200); res.end('halo dunian'); }).mendengarkan(8000); console.log(`Mulai proses pekerja: ${process.pid}`); }
Praktek Aplikasi
Berbagai situasi di mana proses keluar dari Node.js telah dianalisis di atas. Sekarang kita akan membuat alat untuk memantau keluarnya proses. Ketika proses keluar dari Node.js, pengguna diperbolehkan untuk menjalankan logika keluarnya sendiri:
// kait keluar js //Simpan tugas keluar yang perlu dijalankan const task = []; //Tambahkan tugas keluar const addExitTask = fn => task.push(fn); const handleExit = (kode, kesalahan) => { // ...implementasi handleExit ditunjukkan di bawah}; //Dengarkan berbagai event exit process.on('exit', code => handleExit(code)); // Menurut spesifikasi POSIX, kami menggunakan 128 + nomor sinyal untuk mendapatkan kode keluar akhir // Silakan lihat gambar di bawah untuk nomor sinyal. Anda dapat menjalankan kill -l di sistem Linux untuk melihat semua nomor sinyal yang diproses.on ('SIGHUP', () => handleKeluar(128 + 1)); proses.on('SIGINT', () => handleExit(128 + 2)); proses.pada('SIGTERM', () => handleExit(128 + 15)); // Tekan ctrl+break untuk keluar dari proses sinyal.on('SIGBREAK', () => handleExit(128 + 21)); // Kode keluar 1 mewakili kesalahan yang tidak tertangkap yang menyebabkan proses keluar dari proses.on('uncaughtException', error => handleExit(1, error)); process.on('unhandledRejection', error => handleExit(1, error))
;
Selanjutnya kita perlu mengimplementasikan fungsi keluar proses sebenarnya handleExit, karena fungsi tugas yang diteruskan oleh pengguna mungkin sinkron atau asinkron, kita dapat menggunakan process.nextTick untuk memastikan bahwa kode sinkronisasi pengguna telah dijalankan, yang dapat dengan mudah dipahami prosesnya; .nextTick akan dieksekusi setelah eksekusi kode sinkron di setiap tahap loop peristiwa selesai (pahami process.nextTick); untuk tugas asinkron, kami memerlukan pengguna untuk memanggil panggilan balik untuk memberi tahu kami bahwa tugas asinkron telah selesai:
// Tandai apakah itu keluar, Hindari beberapa eksekusi let isExiting = false; const handleExit = (kode, kesalahan) => { jika (isExiting) kembali; isExiting = benar; // Tandai bahwa tindakan keluar telah dilakukan untuk menghindari beberapa panggilan ke let hasDoExit = fasle; const doKeluar = () => { jika (hasDoExit) kembali; hasDoExit = benar proses.nextTick(() => proses.keluar(kode)) } // Catat berapa banyak tugas asinkron yang ada biarkan asyncTaskCount = 0; // Setelah tugas asinkron berakhir, panggilan balik yang perlu dipanggil pengguna let ayncTaskCallback = () => { proses.nextTick(() => { asyncTaskCount-- jika (asyncTaskCount === 0) doExit() }) } //Jalankan semua tugas keluar task.forEach(taskFn => { // Jika jumlah parameter fungsi taskFn lebih besar dari 1, dianggap bahwa parameter panggilan balik diteruskan dan merupakan tugas asinkron jika (taskFn.length > 1) { asyncTaskCount++ taskFn(kesalahan, ayncTaskCallback) } kalau tidak { tugasFn(kesalahan) } }); // Jika ada tugas asinkron if (asyncTaskCount > 0) { // Setelah lebih dari 10 detik, keluar paksa setTimeout(() => { lakukanKeluar(); }, 10*1000) } kalau tidak { lakukanKeluar() } };Pada titik
ini
, alat pemantauan keluar proses kami telah selesai. Untuk implementasi lengkap, Anda dapat melihat pustaka sumber terbuka ini async-exit-hook
https://github.com/darukjs/daruk-exit-hook
keluar dari
server web kami. Saat memulai ulang, dijadwalkan oleh container yang sedang berjalan (pm2 atau buruh pelabuhan, dll.), atau saat terjadi pengecualian dan proses keluar, kami berharap dapat melakukan tindakan keluar, seperti menyelesaikan respons terhadap permintaan yang terhubung ke server. layanan, membersihkan koneksi database, mencetak log kesalahan, memicu alarm, dll., lakukan Setelah menyelesaikan tindakan keluar, dan kemudian keluar dari proses, kita dapat menggunakan alat pemantauan keluar proses sekarang untuk mengimplementasikan:
const http = require(' http'); //Buat server web const server = http.createServer((req, res) => { res.writeHead(200); res.end('halo dunian'); }).mendengarkan(8000); // Gunakan alat yang kami kembangkan di atas untuk menambahkan tugas keluar proses addExitTask((error, callback) => { // Mencetak log kesalahan, memicu alarm, melepaskan koneksi basis data, dll. console.log('Proses keluar secara tidak normal', kesalahan) // Berhenti menerima permintaan baru server.close((error) => { jika (kesalahan) { console.log('Berhenti menerima permintaan baru, kesalahan', kesalahan) } kalau tidak { console.log('Berhenti menerima permintaan baru') } }) // Pendekatan yang lebih sederhana adalah menunggu selama jangka waktu tertentu (di sini kita menunggu 5 detik) hingga permintaan yang ada diselesaikan // Jika Anda ingin benar-benar memastikan bahwa semua permintaan diproses, Anda perlu mencatat setiap koneksi dan menunggu hingga semua koneksi dilepaskan. Jalankan tindakan keluar // Anda dapat merujuk ke perpustakaan sumber terbuka https://github.com/sebhildebrandt/http-graceful-shutdown setTimout(panggilan balik, 5 * 1000) })
Ringkasan
Melalui teks di atas, saya yakin Anda sudah mengetahui berbagai situasi yang menyebabkan proses Node.js keluar. Setelah layanan online, meskipun alat seperti k8s dan pm2 dapat terus menarik proses ketika proses keluar secara tidak normal untuk memastikan ketersediaan layanan, kita juga harus secara aktif merasakan ketidaknormalan atau penjadwalan proses dalam kode, sehingga untuk dapat Menangkap masalah lebih awal.