Di dalam Gelung Peristiwa Node.js: Penyelaman Dalam
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:
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 = [];
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); }
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); } } }
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 = [];
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:
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
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.
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!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas











Python lebih sesuai untuk pemula, dengan lengkung pembelajaran yang lancar dan sintaks ringkas; JavaScript sesuai untuk pembangunan front-end, dengan lengkung pembelajaran yang curam dan sintaks yang fleksibel. 1. Sintaks Python adalah intuitif dan sesuai untuk sains data dan pembangunan back-end. 2. JavaScript adalah fleksibel dan digunakan secara meluas dalam pengaturcaraan depan dan pelayan.

Penggunaan utama JavaScript dalam pembangunan web termasuk interaksi klien, pengesahan bentuk dan komunikasi tak segerak. 1) kemas kini kandungan dinamik dan interaksi pengguna melalui operasi DOM; 2) pengesahan pelanggan dijalankan sebelum pengguna mengemukakan data untuk meningkatkan pengalaman pengguna; 3) Komunikasi yang tidak bersesuaian dengan pelayan dicapai melalui teknologi Ajax.

Aplikasi JavaScript di dunia nyata termasuk pembangunan depan dan back-end. 1) Memaparkan aplikasi front-end dengan membina aplikasi senarai TODO, yang melibatkan operasi DOM dan pemprosesan acara. 2) Membina Restfulapi melalui Node.js dan menyatakan untuk menunjukkan aplikasi back-end.

Memahami bagaimana enjin JavaScript berfungsi secara dalaman adalah penting kepada pemaju kerana ia membantu menulis kod yang lebih cekap dan memahami kesesakan prestasi dan strategi pengoptimuman. 1) aliran kerja enjin termasuk tiga peringkat: parsing, penyusun dan pelaksanaan; 2) Semasa proses pelaksanaan, enjin akan melakukan pengoptimuman dinamik, seperti cache dalam talian dan kelas tersembunyi; 3) Amalan terbaik termasuk mengelakkan pembolehubah global, mengoptimumkan gelung, menggunakan const dan membiarkan, dan mengelakkan penggunaan penutupan yang berlebihan.

Python dan JavaScript mempunyai kelebihan dan kekurangan mereka sendiri dari segi komuniti, perpustakaan dan sumber. 1) Komuniti Python mesra dan sesuai untuk pemula, tetapi sumber pembangunan depan tidak kaya dengan JavaScript. 2) Python berkuasa dalam bidang sains data dan perpustakaan pembelajaran mesin, sementara JavaScript lebih baik dalam perpustakaan pembangunan dan kerangka pembangunan depan. 3) Kedua -duanya mempunyai sumber pembelajaran yang kaya, tetapi Python sesuai untuk memulakan dengan dokumen rasmi, sementara JavaScript lebih baik dengan MDNWebDocs. Pilihan harus berdasarkan keperluan projek dan kepentingan peribadi.

Kedua -dua pilihan Python dan JavaScript dalam persekitaran pembangunan adalah penting. 1) Persekitaran pembangunan Python termasuk Pycharm, Jupyternotebook dan Anaconda, yang sesuai untuk sains data dan prototaip cepat. 2) Persekitaran pembangunan JavaScript termasuk node.js, vscode dan webpack, yang sesuai untuk pembangunan front-end dan back-end. Memilih alat yang betul mengikut keperluan projek dapat meningkatkan kecekapan pembangunan dan kadar kejayaan projek.

C dan C memainkan peranan penting dalam enjin JavaScript, terutamanya digunakan untuk melaksanakan jurubahasa dan penyusun JIT. 1) C digunakan untuk menghuraikan kod sumber JavaScript dan menghasilkan pokok sintaks abstrak. 2) C bertanggungjawab untuk menjana dan melaksanakan bytecode. 3) C melaksanakan pengkompil JIT, mengoptimumkan dan menyusun kod hot-spot semasa runtime, dan dengan ketara meningkatkan kecekapan pelaksanaan JavaScript.

JavaScript digunakan secara meluas di laman web, aplikasi mudah alih, aplikasi desktop dan pengaturcaraan sisi pelayan. 1) Dalam pembangunan laman web, JavaScript mengendalikan DOM bersama -sama dengan HTML dan CSS untuk mencapai kesan dinamik dan menyokong rangka kerja seperti JQuery dan React. 2) Melalui reaktnatif dan ionik, JavaScript digunakan untuk membangunkan aplikasi mudah alih rentas platform. 3) Rangka kerja elektron membolehkan JavaScript membina aplikasi desktop. 4) Node.js membolehkan JavaScript berjalan di sisi pelayan dan menyokong permintaan serentak yang tinggi.
