検索
ホームページウェブフロントエンドjsチュートリアルNode における高い同時実行性の原理の簡単な分析

Node における高い同時実行性の原理の簡単な分析

Oct 18, 2022 pm 08:53 PM
nodejsnode高い同時実行性

Node における高い同時実行性の原理の簡単な分析

最初にいくつかの一般的なステートメントを見てみましょう

  • nodejs はシングルスレッドのノンブロッキング I/O モデルです
  • nodejs は高い同時実行性に適しています
  • nodejs は I/O 集中型のアプリケーションには適していますが、CPU 集中型のアプリケーションには適していません [関連チュートリアルの推奨事項: nodejs ビデオ チュートリアル ]

これらを詳しく分析してみましょう。「はい」とその理由を言う前に、いくつかの準備作業をしてみましょう

最初から始めましょう

一般的な Web アプリケーションは何を行うのかdo

  • 操作 (ビジネス ロジック、数学的演算、関数呼び出しなどを実行します。主な作業は CPU で実行されます)
  • I/O (読み取りやファイルの書き込み、データベースの読み取りと書き込み、ネットワーク リクエストの読み取りと書き込みなど。主にディスクやネットワーク カードなどのさまざまな I/O デバイスで動作します。)

典型的な従来型Web アプリケーションの実装

  • マルチプロセス、1 つのリクエストが I/O をブロックする (子) プロセスをフォークします (つまり、I/O または BIO をブロックします)
  • #Multi-スレッド化すると、1 つのリクエストが I/O をブロックするスレッドを作成します

マルチプロセス Web アプリケーションの例の疑似コード

listenFd = new Socket(); // 创建监听socket
Bind(listenFd, 80); // 绑定端口
Listen(listenFd);   // 开始监听

for ( ; ; ) {
    // 接收客户端请求,通过新的socket建立连接
    connFd = Accept(listenFd);
    // fork子进程
    if ((pid = Fork()) === 0) {
        // 子进程中
        // BIO读取网络请求数据,阻塞,发生进程调度
        request = connFd.read();
        // BIO读取本地文件,阻塞,发生进程调度
        content = ReadFile('test.txt');
        // 将文件内容写入响应
        Response.write(content);
    }
}
マルチスレッド アプリケーションは、実際にはマルチプロセスに似ています。ただし、1 つのリクエストが 1 つのスレッドに割り当てられるのではなく、1 つのリクエストが 1 つのプロセスに割り当てられる点が異なります。スレッドはプロセスよりも軽く、占有するシステム リソースも少なくなります。コンテキスト スイッチング (ps: いわゆるコンテキスト スイッチング、少し説明: シングルコア CPU は同時に 1 つのプロセスまたはスレッドでしかタスクを実行できませんが、インターネット上のマクロの並列処理では、各プロセスやスレッドが実行される機会を確保するために、タイム スライスに従って複数のプロセスやスレッド間を行き来する必要があります。) オーバーヘッドも小さくなり、同時に、スレッド間でメモリを共有することで開発が容易になります

Web アプリケーションの 2 つの核心ポイントは上で述べました。1 つはスレッド (スレッド) モデル、もう 1 つは I/O モデルです。では、I/O をブロックするとは具体的に何でしょうか?他にどのような I/O モデルがありますか?心配しないでください。まず、何がブロックされているかを見てみましょう。

ブロックとは何ですか?ブロッキング I/O とは何ですか?

つまり、ブロッキングとは、関数呼び出しが戻る前に、現在の (スレッド) スレッドが一時停止され、待機状態になることを意味します。この状態では、現在の (スレッド) スレッドは一時停止します。 CPU の受信 (スレッド) プロセスのスケジューリングを引き起こします。この関数は、すべての内部作業が完了した後にのみ呼び出し元に戻ります。

したがって、I/O をブロックするということは、アプリケーションが API を通じて I/O 操作を呼び出した後、現在のスレッド (スレッド) が待機状態にある場合、コードは実行を続行できません。このとき、CPU はスレッド (スレッド) スケジューリングを実行できます。つまり、他の実行可能なスレッドに切り替えて実行を継続します。現在のスレッド (スレッド) が基礎となる I/O の処理を​​完了した後、 O request その場合のみ、戻って実行を継続します

マルチスレッド (スレッド) ブロッキング I/O モデルの何が問題になっていますか?

ブロッキングとブロッキング I/O とは何かを理解した後、従来の Web アプリケーションのマルチスレッド (スレッド) ブロッキング I/O モデルの欠点を分析しましょう。

リクエストにはスレッド(スレッド)を割り当てる必要があるため、同時実行量が多く、多数のコンテキストスイッチが必要な場合、このようなシステムでは多数のスレッド(スレッド)を維持する必要があります。大量の CPU、メモリ サポートなどのシステム リソースが必要となるため、同時リクエストが大量に発生すると、CPU とメモリのオーバーヘッドが急激に増加し、システム全体がすぐにダウンしてサービスが利用できなくなる可能性があります

nodejs アプリケーションの実装

次に、nodejs アプリケーションがどのように実装されるかを見てみましょう。

    イベント駆動型、シングルスレッド (メインスレッド)
  • ノンブロッキング I/O 公式 Web サイトにあるように、nodejs の 2 つの主な機能は、シングルスレッドのイベント駆動型と「ノンブロッキング」I/O モデルです。シングルスレッドのイベント駆動の方が理解しやすいです。フロントエンドの学生は js のシングルスレッドとイベント ループの仕組みをよく知っているはずなので、主にこの「ノンブロッキング I/O」が何であるかを学習しましょう。まず、nodejs サーバー アプリケーションの共通コードを見てみましょう。
const net = require('net');
const server = net.createServer();
const fs = require('fs');

server.listen(80);  // 监听端口
// 监听事件建立连接
server.on('connection', (socket) => {
    // 监听事件读取请求数据
    socket.on('data', (data) => {
    // 异步读取本地文件
    fs.readFile('test.txt', (err, data) => {
            // 将读取的内容写入响应
            socket.write(data);
            socket.end();
        })
    });
});
nodejs では、I/O 操作を非同期で実行できることがわかります。 API を介した操作 すぐに返され、その後は他のコード ロジックの実行を続けることができます。この質問に答える前に、いくつかの準備作業をしましょう。nodejs の高度なビデオ説明を参照してください:

Enter learning

操作の基本手順を読む

最初に確認してください。次の読み取り操作で実行する必要がある手順は何ですか

  • 用户程序调用I/O操作API,内部发出系统调用,进程从用户态转到内核态
  • 系统发出I/O请求,等待数据准备好(如网络I/O,等待数据从网络中到达socket;等待系统从磁盘上读取数据等)
  • 数据准备好后,复制到内核缓冲区
  • 从内核空间复制到用户空间,用户程序拿到数据

接下来我们看一下操作系统中有哪些I/O模型

几种I/O模型

阻塞式I/O

Node における高い同時実行性の原理の簡単な分析


非阻塞式I/O

Node における高い同時実行性の原理の簡単な分析


I/O多路复用(进程可同时监听多个I/O设备就绪)

Node における高い同時実行性の原理の簡単な分析


信号驱动I/O

Node における高い同時実行性の原理の簡単な分析


异步I/O

Node における高い同時実行性の原理の簡単な分析


那么nodejs里到底使用了哪种I/O模型呢?是上图中的“非阻塞I/O”吗?别着急,先接着往下看,我们来了解下nodejs的体系结构

nodejs体系结构,线程、I/O模型分析

Node における高い同時実行性の原理の簡単な分析

最上面一层是就是我们编写nodejs应用代码时可以使用的API库,下面一层则是用来打通nodejs和它所依赖的底层库的一个中间层,比如实现让js代码可以调用底层的c代码库。来到最下面一层,可以看到前端同学熟悉的V8,还有其他一些底层依赖。注意,这里有一个叫libuv的库,它是干什么的呢?从图中也能看出,libuv帮助nodejs实现了底层的线程池、异步I/O等功能。libuv实际上是一个跨平台的c语言库,它在windows、linux等不同平台下会调用不同的实现。我这里主要分析linux下libuv的实现,因为我们的应用大部分时候还是运行在linux环境下的,且平台间的差异性并不会影响我们对nodejs原理的分析和理解。好了,对于nodejs在linux下的I/O模型来说,libuv实际上提供了两种不同场景下的不同实现,处理网络I/O主要由epoll函数实现(其实就是I/O多路复用,在前面的图中使用的是select函数来实现I/O多路复用,而epoll可以理解为select函数的升级版,这个暂时不做具体分析),而处理文件I/O则由多线程(线程池) + 阻塞I/O模拟异步I/O实现


下面是一段我写的nodejs底层实现的伪代码帮助大家理解

listenFd = new Socket();    // 创建监听socket
Bind(listenFd, 80); // 绑定端口
Listen(listenFd);   // 开始监听

for ( ; ; ) {
    // 阻塞在epoll函数上,等待网络数据准备好
    // epoll可同时监听listenFd以及多个客户端连接上是否有数据准备就绪
    // clients表示当前所有客户端连接,curFd表示epoll函数最终拿到的一个就绪的连接
    curFd = Epoll(listenFd, clients);

    if (curFd === listenFd) {
        // 监听套接字收到新的客户端连接,创建套接字
        int connFd = Accept(listenFd);
        // 将新建的连接添加到epoll监听的list
        clients.push(connFd);
    }

    else {
        // 某个客户端连接数据就绪,读取请求数据
        request = curFd.read();
        // 这里拿到请求数据后可以发出data事件进入nodejs的事件循环
        ...
    }
}

// 读取本地文件时,libuv用多线程(线程池) + BIO模拟异步I/O
ThreadPool.run((callback) => {
    // 在线程里用BIO读取文件
    String content = Read('text.txt');  
    // 发出事件调用nodejs提供的callback
});

通过I/O多路复用 + 多线程模拟的异步I/O配合事件循环机制,nodejs就实现了单线程处理并发请求并且不会阻塞。所以回到之前所说的“非阻塞I/O”模型,实际上nodejs并没有直接使用通常定义上的非阻塞I/O模型,而是I/O多路复用模型 + 多线程BIO。我认为“非阻塞I/O”其实更多是对nodejs编程人员来说的一种描述,从编码方式和代码执行顺序上来讲,nodejs的I/O调用的确是“非阻塞”的

总结

至此我们应该可以了解到,nodejs的I/O模型其实主要是由I/O多路复用和多线程下的阻塞I/O两种方式一起组成的,而应对高并发请求时发挥作用的主要就是I/O多路复用。好了,那最后我们来总结一下nodejs线程模型和I/O模型对比传统web应用多进(线)程 + 阻塞I/O模型的优势和劣势

  • nodejs はシングルスレッド モデルを使用して、システムのメンテナンスと複数のスレッドの切り替えのコストを節約します。同時に、多重化 I/O モデルにより、nodejs のシングルスレッドが特定の接続をブロックするのを防ぐことができます。 。 優れた。同時実行性の高いシナリオでは、nodejs アプリケーションは、対応するプロセスやスレッドを作成せずに、複数のクライアント接続に対応するソケット記述子を作成して管理するだけで済みます。システムのオーバーヘッドが大幅に削減されるため、より多くのクライアント接続を同時に処理できます
  • Nodejs基礎となる実際の I/O 操作の効率を向上させることはできません。基盤となる I/O がシステムのパフォーマンスのボトルネックになった場合、nodejs は依然としてそれを解決できません。つまり、nodejs は大量の同時リクエストを受信できますが、大量の低速 I/O 操作 (読み取りや読み取りなど) を処理する必要がある場合、ディスクへの書き込みなど)、それでもシステム リソースの過負荷が発生する可能性があります。したがって、高い同時実行性は、シングルスレッドのノンブロッキング I/O モデルだけでは解決できません。
  • #CPU 集中型のアプリケーションでは、nodejs のシングルスレッド モデルがパフォーマンスのボトルネックになる可能性があります。
  • nodejs は、同時実行性の高い処理に適しています。 少量のビジネス ロジックまたは高速 I/O (メモリの読み書きなど)
  • #ノード関連の知識の詳細については、次のサイトを参照してください:
nodejs チュートリアル

!

以上がNode における高い同時実行性の原理の簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は掘金社区で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
C/CからJavaScriptへ:すべてがどのように機能するかC/CからJavaScriptへ:すべてがどのように機能するかApr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

JavaScriptエンジン:実装の比較JavaScriptエンジン:実装の比較Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

ブラウザを超えて:現実世界のJavaScriptブラウザを超えて:現実世界のJavaScriptApr 12, 2025 am 12:06 AM

現実世界におけるJavaScriptのアプリケーションには、サーバー側のプログラミング、モバイルアプリケーション開発、モノのインターネット制御が含まれます。 2。モバイルアプリケーションの開発は、ReactNativeを通じて実行され、クロスプラットフォームの展開をサポートします。 3.ハードウェアの相互作用に適したJohnny-Fiveライブラリを介したIoTデバイス制御に使用されます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合)Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合)Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

JavaScript:Web言語の汎用性の調査JavaScript:Web言語の汎用性の調査Apr 11, 2025 am 12:01 AM

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

JavaScriptの進化:現在の傾向と将来の見通しJavaScriptの進化:現在の傾向と将来の見通しApr 10, 2025 am 09:33 AM

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

javascriptの分解:それが何をするのか、なぜそれが重要なのかjavascriptの分解:それが何をするのか、なぜそれが重要なのかApr 09, 2025 am 12:07 AM

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。