Rumah > hujung hadapan web > tutorial js > Di dalam Gelung Peristiwa Node.js: Penyelaman Dalam

Di dalam Gelung Peristiwa Node.js: Penyelaman Dalam

Patricia Arquette
Lepaskan: 2025-01-11 20:29:43
asal
1018 orang telah melayarinya

Inside the Node.js Event Loop: A Deep Dive

Penerokaan Model Benang Tunggal Node.js

Node.js mengguna pakai pendekatan I/O dipacu peristiwa dan tak segerak, mencapai persekitaran masa jalan JavaScript berutas tunggal dan sangat serentak. Memandangkan satu utas bermakna hanya satu perkara boleh dilakukan pada satu masa, bagaimanakah Node.js mencapai konkurensi tinggi dan I/O tak segerak dengan hanya satu utas? Artikel ini akan meneroka model satu benang Node.js di sekitar soalan ini.

Strategi Konkurensi Tinggi

Secara amnya, penyelesaian untuk konkurensi tinggi adalah dengan menyediakan model berbilang benang. Pelayan memberikan satu utas kepada setiap permintaan pelanggan dan menggunakan I/O segerak. Sistem ini menebus kos masa panggilan I/O segerak melalui penukaran benang. Sebagai contoh, Apache menggunakan strategi ini. Memandangkan operasi I/O biasanya memakan masa, sukar untuk mencapai prestasi tinggi dengan pendekatan ini. Walau bagaimanapun, ia sangat mudah dan boleh melaksanakan logik interaksi yang kompleks.

Malah, kebanyakan bahagian pelayan web tidak melakukan banyak pengiraan. Selepas menerima permintaan, mereka menghantar permintaan kepada perkhidmatan lain (seperti membaca pangkalan data), kemudian menunggu keputusan kembali, dan akhirnya menghantar hasilnya kepada pelanggan. Oleh itu, Node.js menggunakan model satu benang untuk mengendalikan situasi ini. Daripada memberikan urutan kepada setiap permintaan masuk, ia menggunakan urutan utama untuk mengendalikan semua permintaan dan kemudian memproses operasi I/O secara tidak segerak, mengelakkan overhed dan kerumitan mencipta, memusnahkan utas dan bertukar antara utas.

Gelung Peristiwa

Node.js mengekalkan baris gilir acara dalam urutan utama. Apabila permintaan diterima, ia ditambahkan pada baris gilir ini sebagai acara, dan kemudian ia terus menerima permintaan lain. Apabila utas utama melahu (tiada permintaan masuk), ia mula menggelung melalui baris gilir acara untuk menyemak sama ada terdapat acara yang perlu diproses. Terdapat dua kes: untuk tugasan bukan I/O, utas utama akan mengendalikannya secara terus dan kembali ke lapisan atas melalui fungsi panggil balik; untuk tugasan I/O, ia akan mengambil utas daripada kumpulan utas untuk mengendalikan acara, menentukan fungsi panggil balik, dan kemudian terus menggelung acara lain dalam baris gilir.

Setelah tugas I/O dalam urutan selesai, fungsi panggil balik yang ditentukan akan dilaksanakan dan acara yang telah selesai diletakkan pada penghujung baris gilir acara, menunggu gelung acara. Apabila benang utama bergelung ke acara ini sekali lagi, ia memprosesnya secara langsung dan mengembalikannya ke lapisan atas. Proses ini dipanggil Gelung Peristiwa, dan prinsip operasinya ditunjukkan dalam rajah di bawah:

Inside the Node.js Event Loop: A Deep Dive

Angka ini menunjukkan prinsip operasi keseluruhan Node.js. Dari kiri ke kanan dan dari atas ke bawah, Node.js dibahagikan kepada empat lapisan: lapisan aplikasi, lapisan enjin V8, lapisan API Node dan lapisan LIBUV.

  • Lapisan Aplikasi: Ia ialah lapisan interaksi JavaScript. Contoh biasa ialah modul Node.js seperti http dan fs.
  • Lapisan Enjin V8: Ia menggunakan enjin V8 untuk menghuraikan sintaks JavaScript dan kemudian berinteraksi dengan API lapisan bawah.
  • Lapisan API Nod: Ia menyediakan panggilan sistem untuk modul lapisan atas, biasanya dilaksanakan dalam C dan berinteraksi dengan sistem pengendalian.
  • Lapisan LIBUV: Ia ialah enkapsulasi asas merentas platform yang merealisasikan gelung peristiwa, operasi fail, dll., dan merupakan teras Node.js untuk mencapai tak segerak.

Sama ada pada platform Linux atau platform Windows, Node.js secara dalaman menggunakan kumpulan benang untuk menyelesaikan operasi I/O tak segerak dan LIBUV menyatukan panggilan untuk perbezaan platform yang berbeza. Jadi, utas tunggal dalam Node.js hanya bermakna JavaScript berjalan dalam satu utas, bukannya Node.js secara keseluruhannya berutas tunggal.

Prinsip Kerja

Inti Node.js mencapai tak segerak terletak pada acara. Iaitu, ia menganggap setiap tugas sebagai peristiwa dan kemudian mensimulasikan kesan tak segerak melalui Gelung Acara. Untuk memahami dan menerima fakta ini dengan lebih konkrit dan jelas, kami menggunakan pseudokod untuk menerangkan prinsip kerjanya di bawah.

1. Tentukan Barisan Acara

Memandangkan ia adalah baris gilir, ia adalah struktur data masuk dahulu, keluar dahulu (FIFO). Kami menggunakan tatasusunan JS untuk menerangkannya seperti berikut:

/**
 * Define the event queue
 * Enqueue: push()
 * Dequeue: shift()
 * Empty queue: length === 0
 */
let globalEventQueue = [];
Salin selepas log masuk
Salin selepas log masuk

Kami menggunakan tatasusunan untuk mensimulasikan struktur baris gilir: elemen pertama tatasusunan ialah ketua baris gilir, dan elemen terakhir ialah ekor. push() memasukkan elemen pada penghujung baris gilir, dan shift() mengalih keluar elemen daripada kepala baris gilir. Oleh itu, baris gilir acara mudah dicapai.

2. Tentukan Pintu Masuk Permintaan Penerimaan

Setiap permintaan akan dipintas dan memasuki fungsi pemprosesan, seperti yang ditunjukkan di bawah:

/**
 * Receive user requests
 * Every request will enter this function
 * Pass parameters request and response
 */
function processHttpRequest(request, response) {
    // Define an event object
    let event = createEvent({
        params: request.params, // Pass request parameters
        result: null, // Store request results
        callback: function() {} // Specify a callback function
    });

    // Add the event to the end of the queue
    globalEventQueue.push(event);
}
Salin selepas log masuk

Fungsi ini hanya membungkus permintaan pengguna sebagai acara dan memasukkannya ke dalam baris gilir, kemudian terus menerima permintaan lain.

3. Tentukan Gelung Acara

Apabila utas utama melahu, ia mula berpusing melalui baris gilir acara. Jadi kita perlu menentukan fungsi untuk menggelung melalui baris gilir acara:

/**
 * The main body of the event loop, executed by the main thread when appropriate
 * Loop through the event queue
 * Handle non-IO tasks
 * Handle IO tasks
 * Execute callbacks and return to the upper layer
 */
function eventLoop() {
    // If the queue is not empty, continue to loop
    while (this.globalEventQueue.length > 0) {
        // Take an event from the head of the queue
        let event = this.globalEventQueue.shift();

        // If it's a time-consuming task
        if (isIOTask(event)) {
            // Take a thread from the thread pool
            let thread = getThreadFromThreadPool();
            // Hand it over to the thread to handle
            thread.handleIOTask(event);
        } else {
            // After handling non-time-consuming tasks, directly return the result
            let result = handleEvent(event);
            // Finally, return to V8 through the callback function, and then V8 returns to the application
            event.callback.call(null, result);
        }
    }
}
Salin selepas log masuk

Urut utama sentiasa memantau baris gilir acara. Untuk tugasan I/O, ia menyerahkannya kepada kumpulan benang untuk dikendalikan, dan untuk tugasan bukan I/O, tugas itu mengendalikannya sendiri dan kembali.

4. Mengendalikan Tugasan I/O

Selepas kumpulan benang menerima tugas, ia secara langsung memproses operasi I/O, seperti membaca pangkalan data:

/**
 * Define the event queue
 * Enqueue: push()
 * Dequeue: shift()
 * Empty queue: length === 0
 */
let globalEventQueue = [];
Salin selepas log masuk
Salin selepas log masuk

Apabila tugas I/O selesai, panggilan balik dilaksanakan, hasil permintaan disimpan dalam acara dan acara dimasukkan semula ke dalam baris gilir, menunggu gelung. Akhirnya, benang semasa dikeluarkan. Apabila utas utama bergelung ke acara ini sekali lagi, ia akan memprosesnya secara langsung.

Merumuskan proses di atas, kami mendapati bahawa Node.js hanya menggunakan satu urutan utama untuk menerima permintaan. Selepas menerima permintaan, ia tidak memprosesnya secara langsung tetapi meletakkannya ke dalam baris gilir acara dan kemudian terus menerima permintaan lain. Apabila ia melahu, ia memproses peristiwa ini melalui Gelung Acara, sekali gus mencapai kesan tak segerak. Sudah tentu, untuk tugasan I/O, ia masih perlu bergantung pada kumpulan benang di peringkat sistem untuk dikendalikan.

Oleh itu, kita hanya boleh memahami bahawa Node.js sendiri ialah platform berbilang benang, tetapi ia memproses tugas pada peringkat JavaScript dalam satu urutan.

Tugasan Intensif CPU Adalah Kelemahan

Pada masa ini, kita sepatutnya mempunyai pemahaman yang mudah dan jelas tentang model satu benang Node.js. Ia mencapai konkurensi tinggi dan I/O tak segerak melalui model dipacu peristiwa. Walau bagaimanapun, terdapat juga perkara yang Node.js tidak mahir.

Seperti yang dinyatakan di atas, untuk tugasan I/O, Node.js menyerahkannya kepada kumpulan benang untuk pemprosesan tak segerak, yang cekap dan mudah. Jadi, Node.js sesuai untuk mengendalikan tugas intensif I/O. Tetapi tidak semua tugas adalah I/O-intensif. Apabila menghadapi tugas intensif CPU, iaitu, operasi yang hanya bergantung pada pengiraan CPU, seperti penyulitan dan penyahsulitan data (node.bcrypt.js), pemampatan dan penyahmampatan data (node-tar), Node.js akan mengendalikannya satu demi satu. satu. Jika tugasan sebelumnya tidak selesai, tugasan seterusnya hanya boleh menunggu. Seperti yang ditunjukkan dalam rajah di bawah:

Inside the Node.js Event Loop: A Deep Dive

Dalam baris gilir acara, jika tugas pengiraan CPU sebelumnya tidak diselesaikan, tugasan berikutnya akan disekat, mengakibatkan tindak balas yang perlahan. Jika sistem pengendalian adalah teras tunggal, ia mungkin boleh diterima. Tetapi kini kebanyakan pelayan adalah berbilang CPU atau berbilang teras, dan Node.js hanya mempunyai satu EventLoop, bermakna ia hanya menduduki satu teras CPU. Apabila Node.js diduduki oleh tugas intensif CPU, menyebabkan tugas lain disekat, masih terdapat teras CPU terbiar, mengakibatkan pembaziran sumber.

Jadi, Node.js tidak sesuai untuk tugas intensif CPU.

Senario Aplikasi

  • RETful API: Permintaan dan respons hanya memerlukan sedikit teks dan tidak memerlukan banyak pemprosesan logik. Oleh itu, puluhan ribu sambungan boleh diproses secara serentak.
  • Perkhidmatan Sembang: Ia ringan, mempunyai trafik tinggi dan tidak mempunyai logik pengiraan yang rumit.

Leapcell: Platform Tanpa Pelayan Generasi Seterusnya untuk Pengehosan Web, Tugas Async dan Redis

Inside the Node.js Event Loop: A Deep Dive

Akhir sekali, izinkan saya memperkenalkan platform yang paling sesuai untuk menggunakan perkhidmatan Node.js: Leapcell.

1. Sokongan Pelbagai Bahasa

  • Bangun dengan JavaScript, Python, Go atau Rust.

2. Sebarkan projek tanpa had secara percuma

  • Bayar hanya untuk penggunaan — tiada permintaan, tiada caj.

3. Kecekapan Kos yang tiada tandingan

  • Bayar semasa anda pergi tanpa caj terbiar.
  • Contoh: $25 menyokong 6.94 juta permintaan pada purata masa tindak balas 60ms.

4. Pengalaman Pembangun Diperkemas

  • UI intuitif untuk persediaan mudah.
  • Saluran paip CI/CD automatik sepenuhnya dan penyepaduan GitOps.
  • Metrik masa nyata dan pengelogan untuk mendapatkan cerapan yang boleh diambil tindakan.

5. Kebolehskalaan dan Prestasi Tinggi yang Mudah

  • Penskalaan automatik untuk mengendalikan konkurensi tinggi dengan mudah.
  • Sifar operasi overhed — hanya fokus pada pembinaan.

Inside the Node.js Event Loop: A Deep Dive

Teroka lebih lanjut dalam dokumentasi!

Twitter Leapcell: https://x.com/LeapcellHQ

Atas ialah kandungan terperinci Di dalam Gelung Peristiwa Node.js: Penyelaman Dalam. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan