この記事では主にサーバーとしてのnodejsの原理について説明します。必要な方は参考にしていただければ幸いです。以下のエディターで見てみましょう。
node.js機能Java、PHP、.NETなどのシングルスレッド。新しいスレッドを作成します。各スレッドには約 2MB のメモリが必要です。つまり、理論上、8GB のメモリを搭載したサーバーに同時に接続できる最大ユーザー数は約 4,000 人です。 Web アプリケーションがより多くのユーザーをサポートするには、サーバーの数を増やす必要があり、Web アプリケーションのハードウェア コストも当然増加します。
Node.js は、クライアント接続ごとに新しいスレッドを作成せず、1 つのスレッドのみを使用します。ユーザーが接続すると、内部イベントがトリガーされ、ノンブロッキング I/O およびイベント駆動メカニズムを通じて、Node.js プログラムは巨視的に並列します。 Node.js を使用すると、8 GB のメモリを備えたサーバーで 40,000 人を超えるユーザーの接続を同時に処理できます。
さらに、シングル スレッドによってもたらされる利点は、オペレーティング システムにスレッドの作成と破棄にかかる時間のオーバーヘッドがなくなることです。
2. ノンブロッキングI/O
例えば、データベースにアクセスしてデータを取得する場合、時間がかかります。従来のシングルスレッド処理メカニズムでは、データベースにアクセスするコードを実行した後、スレッド全体が一時停止し、データベースが結果を返すのを待ってから、後続のコードを実行します。 言い換えれば、I/O はコードの実行をブロックし、プログラムの実行効率を大幅に低下させます。 Node.jsで使用されているノンブロッキングI/Oメカニズムにより、データベースにアクセスするコードが実行された後、その背後にあるコードがすぐに実行され、データベースの戻り結果の処理コードはをコールバック関数内に配置することで、プログラムの実行効率が向上します。 I/Oが完了すると、I/O操作を実行しているスレッドにイベントの形式で通知され、スレッドはこのイベントのコールバック関数を実行します。非同期 I/O を処理するには、スレッドにイベント ループが必要で、未処理のイベントがあるかどうかを常にチェックし、順番に処理します。 ブロッキング モードでは、1 つのスレッドは 1 つのタスクのみを処理でき、スループットを向上させるには、マルチスレッドを使用する必要があります。 ノンブロッキングモードでは、スレッドは常に計算操作を実行し、このスレッドのCPUコア使用率は常に100%です。 つまり、これは特に哲学的な解決策です。多くの人を怠けさせるよりも、一人の人が命を危険にさらして死ぬまで働く方が良いのです。 3. イベント駆動型 イベント駆動型
Node では、クライアントが接続の確立、データの送信、その他の動作を要求すると、対応するイベントがトリガーされます。 Node では、一度に 1 つのイベント コールバック関数のみを実行できますが、イベント コールバック関数の実行中に、他のイベント (新しいユーザーの接続など) の処理に切り替えて、戻って実行を続けることができます。元のイベントのコールバック関数、この処理メカニズムは 「イベント ループ」 メカニズムと呼ばれます。 Node.js の最下層は C++ です (V8 も C++ で書かれています)。 基礎となるコードのほぼ半分は、イベント キューとコールバック関数キューの構築に使用されます。イベント駆動型を使用してサーバー タスクのスケジューリングを完了することは、天才だけが思いつくことです。糸を使った針の先の踊りは、多くの仕事をこなす使命を担っています。
シングルスレッド、 シングルスレッドの利点は、メモリのオーバーヘッドとオペレーティング システムのメモリ ページングの削減です。 特定のものが入っても I/O によってブロックされた場合、スレッドはブロックされます。 ノンブロッキングI/O、はI/Oステートメントの終了を待たずに、次のステートメントを実行します。 ノンブロッキングで問題は解決できるでしょうか?たとえば、Xiaohong のビジネスを実行しているときに、Xiaohong の I/O コールバックが完了しました。このとき、どうすればよいでしょうか。 ? イベントメカニズム、イベントループ、新規ユーザーのリクエストであっても、古いユーザーのI/O完了であっても、イベントの形でイベントループに追加され、スケジューリングを待ちます。 3つの特徴と言われていますが、実はそれは1つの特徴であり、誰かがいないと成り立たず、もう遊べません。 Node.js は、多くの人にサービスを提供するためにウェイターを 1 人だけ雇うケチなレストランのオーナーのようなものです。その結果、多くのウェイターよりも効率的になります。 Node.js のすべての I/O は非同期、コールバック関数、コールバック関数のセットです。 開発に適したNode.jsとは何ですか? Node.js はどのようなアプリケーションの開発に適していますか? I/Oは得意、計算は苦手。 Node.js はタスクのスケジューリングに最適であるため、ビジネスに多くの CPU 計算が含まれる場合、実際にはこの計算が単一スレッドをブロックすることになり、Node 開発には適していません。 Node.js は、アプリケーションが大量の同時 I/O を処理する必要があり、クライアントに応答を送信する前にアプリケーション内で非常に複雑な処理を実行する必要がない場合に非常に適しています。 Node.js は、Web ソケットを操作して、接続が長いリアルタイムの対話型アプリケーションを開発するのにも非常に適しています。 例: ● ユーザーフォームコレクション ● 試験システム ● チャットルーム ● グラフィックとテキストのライブストリーミング ● JSON API を提供します (フロントエンド Angular 使用用) Node.jsはPHPやJSPとは異なります ● Node.jsはPHP、JSP、Python、Perl、Rubyとは異なり、独立した言語ではありません。 Node.js はプログラミングに JavaScript を使用し、JavaScript エンジン (V8) で実行されます。 ● PHP、JSPなど(PHP、JSP、.netはすべてサーバープログラム、Apache、Naginx、Tomcat、IISで実行する必要があります)と比較して、Node.jsはApache、Naginx、IISをスキップしますHTTP サーバー自体はサーバー ソフトウェア上に構築する必要はありません。 Node.js の多くの設計概念は、強力なスケーラビリティを提供できる古典的なアーキテクチャ (LAMP = Linux + Apache + MySQL + PHP) とは大きく異なります。 Node.js には Web コンテナ がありません。 例1:ページには「Hello World!」 htdocs ディレクトリにさまざまなサブフォルダーが存在することがよくありますが、指定したページにアクセスするには、ブラウザのアドレス バーに 127.0.0.1:80/app/index.html と入力するだけです 有这么一个文件目录结构:
fang.html 里面是一个 红色的、正方形的p,yuan.html 里面是一个 绿色的、圆形的p 现在新建一个 noWebContainer.js,看能否在url中输入 fang.html 打开页面 运行 127.0.0.1:4000,并在url后面加上 /fang.html,发现完全没用 现在初步对“Node.js没有web容器”这句话有了一点印象了,那想要打开fang.html,怎么办呢? 也就是说,如果 请求的url 里面包含了 /fang,就读取当前目录下(./ ---> 表示当前目录)的 fang.html,否则,就只显示 Hello World 同理,我也可以 输入 /yuan,显示 yuan.html 进一步,在 fang.html 中添加一个图片,从上面的目录结构中可以看到,图片的路径是完全正确的 运行 127.0.0.1:4000/fang,却发现图片破了,说明路径不对。但事实上,我们可以看到,这个路径是一点问题都没有的呀,那怎么办呢? 又回到了那句话,“Node.js没有web容器”,所以,还是要用前面的方法处理一下图片 再次运行,图片可正常显示 现在新建一个 yellow.css 样式表,让 yuan.html 引入这个css 文件 yellow.css 但是,页面的背景颜色没有发生任何改变 看来 “Node.js没有web容器”这句话是无处不在呀,同样需要对 css 文件做处理 再次运行代码,发现页面背景颜色变成了黄色
。 .js には Web コンテナがないため、URL アドレスの後に /xx.xx を入力すると正しく動作しません。 Show <span style="font-size: 14px;">//require表示引包,引包就是引用自己的一个特殊功能<br/>var http = require(‘http‘);<br/>var fs = require(‘fs‘);<br/><br/>//创建服务器,参数是一个回调函数,表示如果有请求进来,要做什么<br/>var server = http.createServer(function(req, res){<br/> <br/> res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"});<br/> res.end("Hello World!");<br/> <br/>});<br/><br/><br/>//运行服务器,监听4000端口(端口号可以任改)<br/>server.listen(4000,"127.0.0.1");<br/></span>
<span style="font-size: 14px;">//require表示引包,引包就是引用自己的一个特殊功能<br/>var http = require(‘http‘);<br/>var fs = require(‘fs‘);<br/><br/>//创建服务器,参数是一个回调函数,表示如果有请求进来,要做什么<br/>var server = http.createServer(function(req, res){<br/> if(req.url==‘/fang‘){<br/> fs.readFile(‘./fang.html‘, function(err,data){<br/> //req表示请求,request; res表示响应,response<br/> //设置HTTP头部,状态码是200,文件类型是html,字符集是utf8<br/> res.writeHead(200, {‘Content-type‘:‘text/html;charset=UTF-8‘});<br/> res.end(data);<br/> })<br/> }else{<br/> res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"});<br/> res.end("Hello World!");<br/> }<br/>});<br/><br/><br/>//运行服务器,监听4000端口(端口号可以任改)<br/>server.listen(4000,"127.0.0.1");<br/></span>
<span style="font-size: 14px;">//require表示引包,引包就是引用自己的一个特殊功能<br/>var http = require(‘http‘);<br/>var fs = require(‘fs‘);<br/><br/>//创建服务器,参数是一个回调函数,表示如果有请求进来,要做什么<br/>var server = http.createServer(function(req, res){<br/> if(req.url==‘/fang‘){<br/> fs.readFile(‘./fang.html‘, function(err,data){<br/> //req表示请求,request; res表示响应,response<br/> //设置HTTP头部,状态码是200,文件类型是html,字符集是utf8<br/> res.writeHead(200, {‘Content-type‘:‘text/html;charset=UTF-8‘});<br/> res.end(data);<br/> })<br/> }else if(req.url==‘/yuan‘){<br/> fs.readFile(‘./yuan.html‘, function(err,data){<br/><br/> res.writeHead(200, {‘Content-type‘:‘text/html;charset=UTF-8‘});<br/> res.end(data);<br/> })<br/> }else{<br/> res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"});<br/> res.end("Hello World!");<br/> }<br/>});<br/><br/><br/>//运行服务器,监听4000端口(端口号可以任改)<br/>server.listen(4000,"127.0.0.1");<br/></span>
<span style="font-size: 14px;"><img src="yule.png" alt="图片"><br/></span>
<span style="font-size: 14px;">//require表示引包,引包就是引用自己的一个特殊功能<br/>var http = require(‘http‘);<br/>var fs = require(‘fs‘);<br/><br/>//创建服务器,参数是一个回调函数,表示如果有请求进来,要做什么<br/>var server = http.createServer(function(req, res){<br/> if(req.url==‘/fang‘){<br/> fs.readFile(‘./fang.html‘, function(err,data){<br/> //req表示请求,request; res表示响应,response<br/> //设置HTTP头部,状态码是200,文件类型是html,字符集是utf8<br/> res.writeHead(200, {‘Content-type‘:‘text/html;charset=UTF-8‘});<br/> res.end(data);<br/> })<br/> }else if(req.url==‘/yuan‘){<br/> fs.readFile(‘./yuan.html‘, function(err,data){<br/><br/> res.writeHead(200, {‘Content-type‘:‘text/html;charset=UTF-8‘});<br/> res.end(data);<br/> })<br/> }else if(req.url==‘/yule.png‘){<br/> fs.readFile(‘./yule.png‘, function(err,data){<br/><br/> res.writeHead(200, {"Content-type":"image/jpg"});<br/> res.end(data);<br/> })<br/> }else{<br/> res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"});<br/> res.end("Hello World!");<br/> }<br/>});<br/><br/><br/>//运行服务器,监听4000端口(端口号可以任改)<br/>server.listen(4000,"127.0.0.1");<br/></span>
<span style="font-size: 14px;">body{background:yellow;}<br/></span>
<span style="font-size: 14px;">//require表示引包,引包就是引用自己的一个特殊功能<br/>var http = require(‘http‘);<br/>var fs = require(‘fs‘);<br/><br/>//创建服务器,参数是一个回调函数,表示如果有请求进来,要做什么<br/>var server = http.createServer(function(req, res){<br/> if(req.url==‘/fang‘){<br/> fs.readFile(‘./fang.html‘, function(err,data){<br/> //req表示请求,request; res表示响应,response<br/> //设置HTTP头部,状态码是200,文件类型是html,字符集是utf8<br/> res.writeHead(200, {‘Content-type‘:‘text/html;charset=UTF-8‘});<br/> res.end(data);<br/> })<br/> }else if(req.url==‘/yuan‘){<br/> fs.readFile(‘./yuan.html‘, function(err,data){<br/><br/> res.writeHead(200, {‘Content-type‘:‘text/html;charset=UTF-8‘});<br/> res.end(data);<br/> })<br/> }else if(req.url==‘/yule.png‘){<br/> fs.readFile(‘./yule.png‘, function(err,data){<br/><br/> res.writeHead(200, {"Content-type":"image/jpg"});<br/> res.end(data);<br/> })<br/> }else if(req.url==‘/yellow‘){<br/> fs.readFile(‘./yellow.css‘, function(err,data){<br/><br/> res.writeHead(200, {"Content-type":"text/css"});<br/> res.end(data);<br/> })<br/> }else{<br/> res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"});<br/> res.end("Hello World!");<br/> }<br/>});<br/><br/><br/>//运行服务器,监听4000端口(端口号可以任改)<br/>server.listen(4000,"127.0.0.1");<br/></span>
以上がサーバーとしてのnodejsの原理についての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。