Node.jsが高速で大量の負荷に対応できることについては、たくさん読んだことがあります。これと他のフレームワーク、特に.Netの実際の証拠は誰にもありますか?私が読んだほとんどの記事は逸話的であるか、.Netとの比較がありません。
ありがとう
Node.jsが高速で大量の負荷に対応できることについては、たくさん読んだことがあります。これと他のフレームワーク、特に.Netの実際の証拠は誰にもありますか?私が読んだほとんどの記事は逸話的であるか、.Netとの比較がありません。
ありがとう
回答:
ビーイングFASTのと取り扱いたくさんLOADは、二つの異なるものです。1秒あたり1つの要求を処理するのに本当に高速なサーバーは、1秒あたり500要求を送信すると(LOADの下で)完全に混雑する可能性があります。
また、静的(およびキャッシュ)ページと動的ページを考慮する必要があります。静的ページについて心配している場合、IISはおそらくノードを打ち負かすでしょう。これは、IISがカーネルモードキャッシュを使用しているためです。
ASP.NETとノードの比較を探していると思います。この戦いでは、すべてがコンパイル/解釈された後、おそらくパフォーマンスがかなり近くなります。たぶん、.NETの小さなFASTERまたは多分、ノード少しだFASTERが、それはおそらく、あなたが気にしないことを十分に近いです。私は.NETに賭けますが、確かではありません。
ノードが本当に説得力のある場所は、LOADを処理するためです。ここでテクノロジーが本当に異なります。ASP.NETは、そのスレッドプールからの各要求にスレッドを割り当てます。ASP.NETが使い果たされると、使用可能なすべてのスレッド要求がキューに入れられ始めます。@shankarの例のような「Hello World」アプリを提供している場合、スレッドはブロックされず、多くのリクエストを処理できるため、これはそれほど重要ではありません。スレッドが不足します。ASP.NETモデルの問題は、スレッドをブロックするI / O要求(DBへの呼び出し、サービスへのhttp要求、ディスクからのファイルの読み取り)を開始するときに発生します。これらのブロッキング要求は、スレッドプールからの貴重なスレッドが何も実行していないことを意味します。ブロッキングが多いほどあなたのASP.NETアプリがロードできるようになるだろうLOAD。
このブロッキングを防ぐには、応答を待つ間、スレッドを保持する必要がないI / O完了ポートを使用します。ASP.NETはこれをサポートしていますが、残念ながら.NETの一般的なフレームワーク/ライブラリの多くはサポートされていません。たとえば、ADO.NETはI / O完了ポートをサポートしますが、Entity Frameworkはそれらを使用しません。したがって、純粋に非同期で多くの負荷を処理するASP.NETアプリを構築できますが、同期のアプリを構築するほど簡単ではないため、ほとんどの人はそうではありません。お気に入りのパーツの一部を使用できない場合があります。フレームワーク(エンティティへのlinqなど)の場合。
問題は、ASP.NET(および.NET Framework)が非同期I / Oについて意見を表明しないように作成されたことです。.NETは、同期コードと非同期コードのどちらを作成してもかまいません。そのため、この決定は開発者に委ねられます。これの一部は、非同期操作でのスレッド化とプログラミングが「難しい」と考えられていたためであり、.NETはすべての人を幸せにしたいと考えていました(初心者や専門家)。.NETは非同期を実行するために3〜4の異なるパターンで終わったので、さらに困難になりました。.NET 4.5は、.NETフレームワークを元に戻して、非同期IOに関する説得力のあるモデルを作成しようとしていますが、関心のあるフレームワークが実際にそれをサポートするまでにはしばらくかかる場合があります。
一方、nodeの設計者は、すべてのI / Oを非同期にする必要があるという独断的な選択をしました。この決定により、ノードの設計者は、ノードの各インスタンスをシングルスレッド化してスレッドの切り替えを最小限に抑え、1つのスレッドがキューに入れられていたコードを実行するという決定を下すこともできました。これは新しいリクエストの場合もあれば、DBリクエストからのコールバックの場合もあれば、作成したhttp restリクエストからのコールバックの場合もあります。ノードは、スレッドコンテキストの切り替えを排除することにより、CPU効率を最大化しようとします。ノードはすべてのI / Oが非同期であるというこの根拠のある選択をしたため、すべてのフレームワーク/アドオンがこの選択をサポートすることも意味します。ノードで100%非同期のアプリを作成する方が簡単です(ノードが非同期のアプリを作成する必要があるため)。
繰り返しになりますが、何らかの方法で証明できる具体的な数値はありませんが、ノードは通常のWebアプリのLOAD競争に勝つと思います。高度に最適化された(100%非同期).NETアプリは、同等のnode.jsアプリにお金を稼ぐ可能性がありますが、すべての.NETとすべてのノードアプリの平均を取った場合、平均して、ノードはおそらくより多くを処理します負荷。
お役に立てば幸いです。
nodejsとIISの間で初歩的なパフォーマンステストを行いました。IISは、「こんにちは、世界!」を提供する場合、nodejsよりも約2.5倍高速です。以下のコード。
私のハードウェア:Dell Latitude E6510、Core i5(デュアルコア)、8 GB RAM、Windows 7 Enterprise 64ビットOS
ノードサーバー
runs at http://localhost:9090/
/// <reference path="node-vsdoc.js" />
var http = require("http");
http.createServer(function (request, response) {
response.writeHead(200, { "Content-Type": "text/html" });
response.write("<p>hello, world!</p>");
response.end();
}).listen(9090);
default.htm
hosted by iis at http://localhost/test/
<p>hello, world!</p>
タスク並列ライブラリを使用した自分のベンチマークプログラム:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
namespace HttpBench
{
class Program
{
private int TotalCount = 100000;
private int ConcurrentThreads = 1000;
private int failedCount;
private int totalBytes;
private int totalTime;
private int completedCount;
private static object lockObj = new object();
/// <summary>
/// main entry point
/// </summary>
static void Main(string[] args)
{
Program p = new Program();
p.Run(args);
}
/// <summary>
/// actual execution
/// </summary>
private void Run(string[] args)
{
// check command line
if (args.Length == 0)
{
this.PrintUsage();
return;
}
if (args[0] == "/?" || args[0] == "/h")
{
this.PrintUsage();
return;
}
// use parallel library, download data
ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = this.ConcurrentThreads;
int start = Environment.TickCount;
Parallel.For(0, this.TotalCount, options, i =>
{
this.DownloadUrl(i, args[0]);
}
);
int end = Environment.TickCount;
// print results
this.Print("Total requests sent: {0}", true, this.TotalCount);
this.Print("Concurrent threads: {0}", true, this.ConcurrentThreads);
this.Print("Total completed requests: {0}", true, this.completedCount);
this.Print("Failed requests: {0}", true, this.failedCount);
this.Print("Sum total of thread times (seconds): {0}", true, this.totalTime / 1000);
this.Print("Total time taken by this program (seconds): {0}", true, (end - start) / 1000);
this.Print("Total bytes: {0}", true, this.totalBytes);
}
/// <summary>
/// download data from the given url
/// </summary>
private void DownloadUrl(int index, string url)
{
using (WebClient client = new WebClient())
{
try
{
int start = Environment.TickCount;
byte[] data = client.DownloadData(url);
int end = Environment.TickCount;
lock (lockObj)
{
this.totalTime = this.totalTime + (end - start);
if (data != null)
{
this.totalBytes = this.totalBytes + data.Length;
}
}
}
catch
{
lock (lockObj) { this.failedCount++; }
}
lock (lockObj)
{
this.completedCount++;
if (this.completedCount % 10000 == 0)
{
this.Print("Completed {0} requests.", true, this.completedCount);
}
}
}
}
/// <summary>
/// print usage of this program
/// </summary>
private void PrintUsage()
{
this.Print("usage: httpbench [options] <url>");
}
/// <summary>
/// print exception message to console
/// </summary>
private void PrintError(string msg, Exception ex = null, params object[] args)
{
StringBuilder sb = new System.Text.StringBuilder();
sb.Append("Error: ");
sb.AppendFormat(msg, args);
if (ex != null)
{
sb.Append("Exception: ");
sb.Append(ex.Message);
}
this.Print(sb.ToString());
}
/// <summary>
/// print to console
/// </summary>
private void Print(string msg, bool isLine = true, params object[] args)
{
if (isLine)
{
Console.WriteLine(msg, args);
}
else
{
Console.Write(msg, args);
}
}
}
}
と結果:
IIS: httpbench.exe http://localhost/test
Completed 10000 requests.
Completed 20000 requests.
Completed 30000 requests.
Completed 40000 requests.
Completed 50000 requests.
Completed 60000 requests.
Completed 70000 requests.
Completed 80000 requests.
Completed 90000 requests.
Completed 100000 requests.
Total requests sent: 100000
Concurrent threads: 1000
Total completed requests: 100000
Failed requests: 0
Sum total of thread times (seconds): 97
Total time taken by this program (seconds): 16
Total bytes: 2000000
nodejs: httpbench.exe http://localhost:9090/
Completed 10000 requests.
Completed 20000 requests.
Completed 30000 requests.
Completed 40000 requests.
Completed 50000 requests.
Completed 60000 requests.
Completed 70000 requests.
Completed 80000 requests.
Completed 90000 requests.
Completed 100000 requests.
Total requests sent: 100000
Concurrent threads: 1000
Total completed requests: 100000
Failed requests: 0
Sum total of thread times (seconds): 234
Total time taken by this program (seconds): 27
Total bytes: 2000000
結論:IISはnodejsよりも約2.5倍高速です(Windowsの場合)。これは非常に初歩的なテストであり、決して決定的なものではありません。しかし、これは良い出発点だと思います。Nodejsは他のWebサーバーや他のプラットフォームではおそらくより高速ですが、WindowsではIISが勝っています。ASP.NET MVCをnodejsに変換することを検討している開発者は、先に進む前に一時停止してよく考える必要があります。
更新(2012年5月17日)Tomcat(Windows上)は、静的なHTMLを提供する際にIISの約3倍の速さでIISの手を打ち負かすようです。
トムキャット
index.html at http://localhost:8080/test/
<p>hello, world!</p>
tomcatの結果
httpbench.exe http://localhost:8080/test/
Completed 10000 requests.
Completed 20000 requests.
Completed 30000 requests.
Completed 40000 requests.
Completed 50000 requests.
Completed 60000 requests.
Completed 70000 requests.
Completed 80000 requests.
Completed 90000 requests.
Completed 100000 requests.
Total requests sent: 100000
Concurrent threads: 1000
Total completed requests: 100000
Failed requests: 0
Sum total of thread times (seconds): 31
Total time taken by this program (seconds): 5
Total bytes: 2000000
更新された結論:ベンチマークプログラムを複数回実行しました。Tomcatは、WINDOWS上の静的HTMLを提供する最速のサーバーのようです。
更新(2012年5月18日)以前は、合計で100,000のリクエストがあり、10,000の同時リクエストがありました。私はそれを1,000,000の総requesと100,000の同時リクエストに増やしました。IISは最悪の勝利を収め、Nodejsは最悪の事態を招きました。以下の結果を表にまとめました。
。
NIOサーバー(Node.jsなど)は、BIOサーバーよりも高速になる傾向があります。(IISなど)。私の主張を裏付けるために、TechEmpowerはWebフレームワークベンチマークに特化した会社です。それらは非常にオープンで、すべてのフレームワークをテストする標準的な方法があります。
ラウンド9テストは現在最新です(2014年5月)。テストされたIISフレーバーは多数ありますが、aspnet-strippedは最も速いIISバリアントのようです。
1秒あたりの応答の結果を次に示します(高いほど良い)。
228,887
105,272
88,597
47,066
8,878
3,915
289,578
109,136
すべての場合において、Node.jsはIISの2倍以上高速になる傾向があります。
私はマーカス・グランストロームに同意する必要があります。シナリオはここで非常に重要です。
正直に言うと、アーキテクチャに大きな影響を与えているように思えます。私のアドバイスは、懸念のある領域を分離し、検討しているスタック間で「ベイクオフ」を行うことです。
結局のところ、あなたが決定の責任を負うので、言い訳はないと思います。
私が目にする主な違いは、node .jsは動的プログラミング言語(型チェック)であるため、型は実行時に派生する必要があるということです。C#.NETのような強く型付けされた言語は、理論的にはノード.js(およびPHPなど)との戦いに勝つ可能性がはるかに高くなります。ちなみに、.NETは、ノード.jsよりもC / C ++とのネイティブな相互運用が優れている必要があります。