我已经阅读了很多有关Node.js的快速信息,并能够承受大量负载。有人在现实世界中有证据证明与其他框架相比,特别是.Net吗?我读过的大多数文章都是轶事,或者没有与.Net的比较。
谢谢
我已经阅读了很多有关Node.js的快速信息,并能够承受大量负载。有人在现实世界中有证据证明与其他框架相比,特别是.Net吗?我读过的大多数文章都是轶事,或者没有与.Net的比较。
谢谢
Answers:
作为FAST和处理大量的负载是两回事。如果您每秒发送500个请求(在LOAD下),那么实际上每秒处理一个请求的速度非常快的服务器可能完全崩溃。
您还必须考虑静态(和缓存)与动态页面。如果您担心静态页面,则IIS可能会击败节点,因为IIS使用内核模式缓存,这意味着请求静态页面的请求甚至都不会脱离内核。
我猜您正在寻找ASP.NET与节点之间的比较。在这场战斗中,在对所有内容进行编译/解释之后,您的性能可能会非常接近。也许.NET有点更快或许节点是一个小更快,但它可能接近,以至于你不在乎。我打赌.NET,但是我不确定。
节点真正引人注目的地方是处理LOAD。这是技术真正不同之处。ASP.NET为来自其线程池的每个请求专用一个线程,一旦ASP.NET用尽了所有可用线程的请求,便开始排队。如果您像@shankar的示例一样在服务“ Hello World”应用程序,那么这可能没什么大不了的,因为不会阻塞线程,并且您将能够处理很多请求,然后再处理用完线程。当您开始发出阻止线程的I / O请求(调用DB,向服务发出http请求,从磁盘读取文件)时,ASP.NET模型就会出现问题。这些阻塞请求意味着您来自线程池的宝贵线程无所作为。您拥有的障碍越多,加载您的ASP.NET应用即可。
为了防止这种阻塞,可以使用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的自以为是的模型,但是直到您关心的框架实际支持它时,可能还需要一段时间。
另一方面,节点的设计者做出了明智的选择,即所有I / O应该异步。由于这一决定,节点设计者还能够做出以下决定:每个节点实例将是单线程的,以最大程度地减少线程切换,并且一个线程将仅执行已排队的代码。那可能是一个新请求,可能是来自数据库请求的回调,也可能是来自您发出的http rest请求的回调。节点尝试通过消除线程上下文切换来最大化CPU效率。因为节点选择所有I / O都是异步的,所以这也意味着它的所有框架/附加组件都支持该选择。在节点中编写100%异步的应用程序会更容易(因为节点会强制您编写异步的应用程序)。
同样,我没有任何硬性数字可以证明一种方法,但是我认为节点将赢得典型Web应用程序的LOAD竞争。高度优化的(100%异步).NET应用程序可能会花钱让等效的node.js应用程序运行,但是,如果您平均使用所有.NET和其中的所有节点应用程序,则平均而言,节点可能会处理更多加载。
希望有帮助。
我在nodejs和IIS之间进行了基本的性能测试。抛出“ hello,world!”时,IIS的速度大约是nodejs的2.5倍。下面的代码。
我的硬件:Dell Latitude E6510,Core i5(双核),8 GB RAM,Windows 7 Enterprise 64位操作系统
节点服务器
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上)。这是一个非常基本的测试,绝不是结论性的。但是我相信这是一个很好的起点。在其他Web服务器和其他平台上,Nodejs可能更快,但在Windows IIS上胜出。希望将ASP.NET MVC转换为nodejs的开发人员应该暂停并三思而后行。
已更新(5/17/2012)Tomcat(在Windows上)似乎击败了IIS,在抛出静态html方面比IIS快约3倍。
雄猫
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上分发STATIC HTML的最快服务器。
更新日期(5/18/2012)以前,我总共有100,000个请求,同时有10,000个并发请求。我将其增加到1,000,000个总请求和100,000个并发请求。IIS成为尖叫的赢家,Nodejs表现最差。我将以下结果制成表格:
。
NIO服务器(Node.js等)往往比BIO服务器要快。(IIS等)。为了证明我的观点,TechEmpower是一家专门从事Web框架基准测试的公司。它们非常开放,并且具有测试所有framewrks的标准方法。
第9轮测试目前是最新的(2014年5月)。已经测试了许多IIS风格,但是aspnet剥离的似乎是最快的IIS变体。
以下是每秒响应的结果(越高越好):
228,887
105,272
88,597
47,066
8,878
3,915
289,578
109,136
在所有情况下,Node.js的速度往往都比IIS快2倍以上。
我必须同意Marcus Granstrom的观点,在这里非常重要。
老实说,这听起来像是您在做出具有重大影响的建筑决策。我的建议是隔离关注的区域,并在您考虑的所有堆栈之间进行“烘焙”。
归根结底,您要对决定负责,我不认为借口“ Stackoverflow上的某人向我展示了一篇文章,说那会很好的”会与您的老板削减。
我看到的主要区别是node .js是动态编程语言(类型检查),因此类型必须在运行时派生。从理论上讲,像C#.NET这样的强类型语言在与Node .js(和PHP等)的对抗中具有更大的潜力,尤其是在计算成本很高的地方。顺便说一句,.NET与C / C ++的本地互操作性应优于节点.js。