検索
ホームページウェブフロントエンドjsチュートリアルNode.js の高同時実行性と分散クラスタリングに関する簡単な説明

この記事では、node.js における高同時実行性と分散クラスターについて簡単に説明します。必要な方は参考にしていただければ幸いです。

ノードの機能: 高い同時実行性

なぜノードが高い同時実行性を達成できるのかを説明する前に、ノードの他のいくつかの機能を理解しておくとよいでしょう:

シングルスレッド

まず概念を明確にしましょう。つまり、ノードは シングルスレッド、これはブラウザのJavaScriptの特性と同じであり、ノードでは、JavaScriptのメインスレッドは他のスレッド(I/Oスレッドなど)と状態を共有できません。 单线程的,这一点与JavaScript在浏览器中的特性相同,并且在node中JavaScript主线程与其他线程(例如I/O线程)是无法共享状态的。

单线程的好处就是:

  • 无需像多线程那样去关注线程之间的状态同步问题

  • 没有线程切换所带来的开销

  • 没有死锁存在

当然单线程也有许多坏处:

  • 无法充分利用多核CPU

  • 大量计算占用CPU会导致应用阻塞(即不适用CPU密集型)

  • 错误会引起整个应用的退出

不过在今天看来,这些坏处都已经不再是问题或者得到了适当的解决:

(1) 创建进程 or 细分实例

关于第一个问题,最直白解决方案就是使用child_process核心模块或者cluster:child_process 和 net 组合应用。我们可以通过在一台多核服务器上创建多个进程(通常使用fork操作)来充分利用每个核心,不过要处理好进程间通信问题。

另一个方案是,我们可以将物理机器划分为多台单核的虚拟机,并通过pm2等工具,管理多台虚拟机形成一个集群架构,高效运行所需服务,至于每台机器间的通信(状态同步)我这里先按下不表,在下文的Node分布式架构中再做详细说明。

(2) 时间片轮转

关于第二点,我跟小伙伴讨论过后认为可以通过时间片轮转方式,在单线程上模拟多线程,适当减少应用阻塞的感觉(虽然这种方法不会真的像多线程那样节约时间)

(3) 负载均衡、坏点监控/隔离

至于第三点,我跟小伙伴们也讨论过,认为主要的痛点就在于node不同于JAVA,它所实现的逻辑是以异步为主的。

这就导致了node无法像JAVA一样方便地使用 try/catch 来来捕获并绕过错误,因为无法确定异步任务会何时传回异常。而在单线程环境下,绕不过错误就意味着导致应用退出,重启恢复的间隙会导致服务中断,这是我们不愿意看到的。

当然,在服务器资源丰富的当下,我们可以通过 pm2 或 nginx 这些工具,动态的判断服务状态。在服务出错时隔离坏点服务器,将请求转发到正常服务器上,并重启坏点服务器以继续提供服务。这也是Node分布式架构的一部分。

异步I/O

你可能会问,既然node是单线程的,事件全部在一个线程上处理,那不是应该效率很低、与高并发相悖吗?

恰恰相反,node的性能很高。原因之一就是node具有异步I/O特性,每当有I/O请求发生时,node会提供给该请求一个I/O线程。然后node就不管这个I/O的操作过程了,而是继续执行主线程上的事件,只需要在该请求返回回调时在处理即可。也就是node省去了许多等待请求的时间。

这也是node支持高并发的重要原因之一

实际上不光是I/O操作,node的绝大多数操作都是以这种异步的方式进行的。它就像是一个组织者,无需事必躬亲,只需要告诉成员们如何正确的进行操作并接受反馈、处理关键步骤,就能使得整个团队高效运行。

事务驱动

你可能又要问了,node怎么知道请求返回了回调,又应该何时去处理这些回调呢?

答案就是node的另一特性:事务驱动

シングルスレッドの利点は次のとおりです:

マルチスレッドのようなスレッド間の状態同期の問題に注意を払う必要がありません

スレッドの切り替えによるオーバーヘッドがありません

デッドロック

  • もちろん、シングルスレッドには多くの欠点もあります:

マルチコア CPU を完全に活用できない

  • CPU を占有する大量の計算により、アプリケーションのブロックが発生します (つまり、CPU に適さない) -集中的)

  • エラーによりアプリケーション全体が終了します

    🎜 🎜しかし、現在では、これらの欠点は問題ではなくなっているか、適切に解決されているようです: 🎜🎜(1) プロセスを作成するか、インスタンスを細分化する🎜🎜 最初の問題に関して、最も簡単な解決策は、child_process コア モジュールまたはクラスター: child_process と net を組み合わせたアプリケーションを使用することです。マルチコア サーバー上に複数のプロセスを作成する (通常はフォーク操作を使用する) ことで各コアを最大限に活用できますが、プロセス間の通信の問題に対処する必要があります。 🎜🎜もう 1 つの解決策は、物理マシンを複数のシングルコア仮想マシンに分割し、pm2 などのツールを使用して複数の仮想マシンを管理し、必要なサービスを効率的に実行するためのクラスター アーキテクチャを形成することです。通信(状態同期) ここでは今回は記載せず、以下のノード分散アーキテクチャで詳しく説明します。 🎜🎜(2) タイムスライスローテーション🎜🎜 2点目については、友達と話し合った結果、タイムスライスローテーションを使ってシングルスレッド上でマルチスレッドをシミュレートし、アプリケーションのブロッキング感を適切に軽減できるのではないかと思います(ただしこれは問題ありません)。マルチスレッドのように本当に時間を節約できます)🎜🎜(3) 負荷分散、不良ピクセルの監視/分離🎜🎜 3番目の点については、私も友人と議論しましたが、主な問題点はノードは JAVA とは異なり、実装されるロジックは主に非同期です。 🎜🎜これにより、非同期タスクがいつ例外を返すかを判断することが不可能なため、ノードは try/catch を使用して JAVA と同様にエラーをキャッチしてバイパスすることができなくなります。シングルスレッド環境では、エラーのバイパスに失敗するとアプリケーションが終了することを意味し、再起動と回復の間のギャップによりサービスが中断されることになりますが、これは望ましくないことです。 🎜🎜もちろん、今ではサーバーリソースが豊富なので、pm2やnginxなどのツールを使用してサービスの状態を動的に判断できます。サービス エラーが発生した場合は不良ピクセル サーバーを隔離し、リクエストを通常のサーバーに転送し、不良ピクセル サーバーを再起動してサービスの提供を継続します。これも Node の分散アーキテクチャの一部です。 🎜🎜非同期 I/O🎜🎜 ノードはシングルスレッドであり、すべてのイベントが 1 つのスレッドで処理されるため、非同期 I/O は非常に非効率であり、高い同時実行性に反するのではないかと疑問に思われるかもしれません。 🎜🎜それどころか、ノードのパフォーマンスは非常に高いです。理由の 1 つは、ノードに 非同期 I/O 機能があるため、I/O リクエストが発生すると、そのリクエストに対して I/O スレッドが提供されます。その後、ノードは I/O 操作プロセスを気にせず、メインスレッドでイベントを実行し続けますが、リクエストがコールバックを返したときにのみ処理する必要があります。つまり、ノードはリクエストを待つ時間を大幅に節約します。 🎜🎜🎜これは、ノードが高い同時実行性をサポートする重要な理由の 1 つでもあります🎜🎜🎜実際、I/O 操作だけでなく、ノードのほとんどの操作はこの非同期方法で実行されます。オーガナイザーは、個人的にすべてを行う必要はなく、チーム全体が効率的に運営できるように、メンバーに正しい操作方法、フィードバックの受け入れ方法、主要な手順の処理方法を伝えるだけで済みます。 🎜🎜トランザクション駆動🎜🎜もう一度尋ねたいかもしれませんが、ノードはリクエストがコールバックを返したことをどのようにして知るのでしょうか?また、これらのコールバックをいつ処理する必要があるのでしょうか? 🎜🎜その答えは、ノードのもう 1 つの機能である トランザクション ドライバー です。つまり、メイン スレッドがイベント ループ トリガーを通じてプログラムを実行します 🎜🎜🎜これが、ノードが高い同時実行性をサポートするもう 1 つの重要な理由です 🎜🎜 🎜ノード環境のイベント ループの図: 🎜
       ┌───────────────────────┐
    ┌─>│        timers         │🎜🎜ポーリング フェーズ: 🎜🎜🎜ポーリング フェーズに入り、タイマーが呼び出されないと、次の状況が発生します: 🎜🎜 (1) ポーリング キューが空でない場合 : 🎜🎜🎜🎜イベント ループは、キューが空になるか、実行されたコールバックがオンラインになるまで、ポーリング キュー内のコールバック (新しい I/O イベント) を同期的に実行します。 🎜🎜🎜🎜(2) ポーリング キューが空の場合: 🎜🎜🎜🎜 スクリプトが setImmediate() を呼び出すと、イベント ループはポーリング フェーズを終了し、setImmediate() コールバックを実行するチェック フェーズに入ります。 🎜🎜🎜🎜スクリプトが setImmediate() によって呼び出されない場合、イベント ループはコールバック (新しい I/O イベント) がキューに追加されるのを待機し、すぐに実行します。 🎜

ポーリングフェーズに入り、タイマーが呼び出されると、次のことが起こります:

  • ポーリングキューが空になると、イベントループはタイマーがあるかどうかを確認し、1つ以上のタイマーが到着した場合、イベントループは戻りますタイマー フェーズに移行し、それらのタイマー コールバックを実行します (つまり、次のティックを入力します)。

Priority:

Next Tick Queue > MicroTask Queue

setTimeout, setInterval > setImmediate

タイマーは時間が到来したかどうかを判断するために赤黒ツリーからタイマーを取り出す必要があるため、時間計算量は O (lg(n)) なので、イベントを非同期ですぐに実行したい場合は、setTimeout(func, 0) を使用しないことをお勧めします。代わりに process.nextTick() を使用してこれを実行します。

分散ノードアーキテクチャ

私が学んだノードクラスターアーキテクチャは主に次のモジュールに分かれています:

Nginx (ロードバランシング、スケジューリング) -> ノードクラスター -> Redis (同期ステータス)

コンパイルしました私の理解に基づく図:

Node.js の高同時実行性と分散クラスタリングに関する簡単な説明

もちろん、これは理想的なアーキテクチャであるはずです。 Redis の読み取り/書き込みは非常に高速ですが、これはメモリ プールにデータを保存し、メモリ上で関連する操作を実行するためです。

これはサーバーのメモリ負荷としては非常に高いので、通常は以下に示すように Mysql をアーキテクチャに追加します:

Node.js の高同時実行性と分散クラスタリングに関する簡単な説明

まずこの図について説明します:
ユーザーデータが到着すると、データは次のように書き込みます。まず Mysql にアクセスし、ノードでデータが必要なときに Redis にアクセスして読み取ります。データが見つからない場合は、Mysql にアクセスして目的のデータをクエリし、次回使用するときに Redis に直接アクセスしてください。クエリ。

Redis での読み取り/書き込みのみと比較した Mysql の追加の利点は次のとおりです:

(1) 短期的に Redis に無駄なデータを書き込むことを避け、メモリを占有し、Redis の負担を軽減します

(2) 修正が必要後の段階のデータ 特定のクエリと分析 (運用アクティビティのユーザーの増加の分析など) を実行する場合、SQL リレーショナル クエリは大きな助けになります

もちろん、短期的な大量の書き込みを処理する場合は、データを Redis に直接書き込むこともできます。データを迅速に保存し、トラフィックに対処するサーバーの能力を高めるという目的を達成するために、データはトラフィックが落ち着いたときに個別に MySQL に書き込まれます。

一般的なアーキテクチャを簡単に紹介した後、各部分の詳細を詳しく見てみましょう:

トラフィック アクセス層

トラフィック アクセス層の機能は、受け入れられたすべてのトラフィックを処理し、次のサービスを提供することです:

  • トラフィックバッファリング

  • 迂回と転送

Node.js の高同時実行性と分散クラスタリングに関する簡単な説明

  • タイムアウト検出

    • ユーザーとの接続を確立するためのタイムアウト

    • ユーザー本体がタイムアウトしました
    • 接続バックエンドタイムアウト
    • バックエンド応答ヘッダーの読み取りタイムアウト
    • 書き込み応答タイムアウト
    • ユーザーとの長い接続タイムアウト
    クラスターのヘルスチェック/不良サーバーの隔離
    • 不良サーバーをクリックそして試してみてくださいサーバーが正常に戻るまで修復/再起動します
    失敗再試行メカニズム
    • リクエストが特定のクラスタ内の特定のマシンに転送され、失敗が返された後、リクエストはクラスタ内の別のマシンに転送されます。クラスター、またはクラスター間のマシンで再試行します
    接続プール/セッション永続化メカニズム
    • 遅延に敏感なユーザーは、接続を確立する時間を短縮するために接続プールメカニズムを使用してください
    セキュリティ保護
  • データ分析
  • 各製品ラインに転送した後、負荷層が機能します。状況に応じてリクエストをさまざまなコンピュータールームに転送します

Node.js の高同時実行性と分散クラスタリングに関する簡単な説明もちろん、このプラットフォームはこの機能を転送するだけでなく、次のサービスを提供する大規模なプライベート クラウド システムとして理解できます:

    ファイルのアップロード/サービスのオンライン展開
  • オンライン構成の変更
  • スケジュールされたタスクの設定
  • オンラインシステム監視/ログ印刷サービス
  • オンラインインスタンス管理
  • ミラーセンター
  • など...
  • ノードクラスターレイヤー

この層の主な仕事は次のとおりです。

(1 )信頼性の高いノードコードを作成し、ニーズに合わせたバックエンドサービスを提供します

(2) 高パフォーマンスのクエリ ステートメントを作成し、Redis および Mysql と対話し、クエリ効率を向上させます

(3) Redis を介してクラスター内の各ノード サービスのステータスを同期します

(4) を介して物理マシンを管理/監視しますハードウェア管理プラットフォームのステータス、管理 IP アドレスなど (実際、作業のこの部分をこの層に配置するのは不適切な気がしますが、どの層に配置すればよいのかわかりません...)

(もちろん、この部分のエントリは簡単に列挙するだけですが、蓄積して深く理解するには時間がかかります)

データベース層

この層の主な作業は次のとおりです:

(1) MySQL の作成と関連するページとテーブルの設計; クエリの利便性を向上させるために必要なインデックスと外部キーを確立します

(2) Redis をデプロイし、対応するインターフェイスをノード層に提供します

関連する推奨事項:

vue がバックエンドデータをリクエストするためにどのように axios を使用するか

Vue のフォーム入力バインディングとコンポーネントの基本

以上がNode.js の高同時実行性と分散クラスタリングに関する簡単な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
Linux中如何构建4块虚拟盘来搭建分布式MinIO集群?Linux中如何构建4块虚拟盘来搭建分布式MinIO集群?Feb 10, 2024 pm 04:48 PM

由于最近刚开始负责对象存储相关系统的建设与稳定性运维,作为一个“对象存储”的一个新手,需要加强这块的学习。由于公司目前采用MinIO来搭建公司的对象存储体系,后续我会逐步将自己关于MinIO的学习经验分享出来,欢迎大家持续关注。本文主要是介绍如何在测试环境中搭建MinIO,这也是构建MinIO学习环境最基本的步骤。1、准备实验环境使用OracleVMVirtualBox虚拟机,安装一个最小版本的Linux,然后添加4块虚拟盘,用于充当MinIO的虚拟盘。实验环境如下所示:接下来和大家简单介绍一下

Vercel是什么?怎么部署Node服务?Vercel是什么?怎么部署Node服务?May 07, 2022 pm 09:34 PM

Vercel是什么?本篇文章带大家了解一下Vercel,并介绍一下在Vercel中部署 Node 服务的方法,希望对大家有所帮助!

node.js gm是什么node.js gm是什么Jul 12, 2022 pm 06:28 PM

gm是基于node.js的图片处理插件,它封装了图片处理工具GraphicsMagick(GM)和ImageMagick(IM),可使用spawn的方式调用。gm插件不是node默认安装的,需执行“npm install gm -S”进行安装才可使用。

node爬取数据实例:聊聊怎么抓取小说章节node爬取数据实例:聊聊怎么抓取小说章节May 02, 2022 am 10:00 AM

node怎么爬取数据?下面本篇文章给大家分享一个node爬虫实例,聊聊利用node抓取小说章节的方法,希望对大家有所帮助!

手把手带你使用Node.js和adb开发一个手机备份小工具手把手带你使用Node.js和adb开发一个手机备份小工具Apr 14, 2022 pm 09:06 PM

本篇文章给大家分享一个Node实战,介绍一下使用Node.js和adb怎么开发一个手机备份小工具,希望对大家有所帮助!

使用Gin框架实现分布式部署和管理功能使用Gin框架实现分布式部署和管理功能Jun 22, 2023 pm 11:39 PM

随着互联网的发展和应用,分布式系统也越来越受到人们的关注和重视。而在分布式系统中,如何实现快速部署和便捷管理则成为了一项必要的技术。本文将介绍如何使用Gin框架来实现分布式系统的部署和管理功能。一、分布式系统部署分布式系统的部署主要包括了代码部署、环境部署、配置管理和服务注册等几个方面。以下将逐一介绍这些方面。代码部署在分布式系统中,代码部署是一个重要的环节

node.js后台框架有哪些node.js后台框架有哪些Jul 11, 2022 pm 06:20 PM

node后台框架有:1、Koa,一个开源的Node web框架,用Generator来实现中间件的流程控制,用try/catch来增强异常处理;2、Nest,一个用于构建高效、可扩展的Node服务器端应用程序的框架;3、Socket,是用来在客户端和服务器端之间创建实时双向通信的框架;4、Sails,是一个非常稳固的Node框架,提供建立任何规模的Web应用所需要的所有功能。

聊聊Node.js path模块中的常用工具函数聊聊Node.js path模块中的常用工具函数Jun 08, 2022 pm 05:37 PM

本篇文章带大家聊聊Node.js中的path模块,介绍一下path的常见使用场景、执行机制,以及常用工具函数,希望对大家有所帮助!

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ヘンタイを無料で生成します。

ホットツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター