Я багато читав про швидкість Node.js і вміст вмістити велику кількість навантаження. Хто-небудь має реальні свідоцтва цього чи інших рамок, зокрема. Net? Більшість прочитаних нами статей є анекдотичними або не мають порівнянь з .Net.
Дякую
Я багато читав про швидкість Node.js і вміст вмістити велику кількість навантаження. Хто-небудь має реальні свідоцтва цього чи інших рамок, зокрема. Net? Більшість прочитаних нами статей є анекдотичними або не мають порівнянь з .Net.
Дякую
Відповіді:
Будучи ШВИДКО і обробкою багато НАВАНТАЖЕННЯ дві різними речей. Сервер, який дійсно Швидкий при обслуговуванні одного запиту в секунду, може цілком зламатись, якщо ви надішлете йому 500 запитів в секунду (під LOAD ).
Ви також повинні враховувати статичні (і кешовані) та динамічні сторінки. Якщо ви переживаєте за статичні сторінки, то IIS, ймовірно, збирається бити вузол, оскільки IIS використовує кешування в режимі ядра, а це означає, що запити, які запитують статичну сторінку, навіть не збираються виходити з ядра.
Я здогадуюсь, що ви шукаєте порівняння між ASP.NET та вузлом. У цьому бою, після того, як все буде складено / інтерпретовано, ви, ймовірно, будете досить близькими у виконанні. Можливо .NET трохи швидше, а може, вузол трохи швидше , але, мабуть, досить близько, що вам все одно. Я ставлю на .NET, але точно не знаю.
Місце, де вузол дійсно є переконливим, - це обробка НАВАНТАЖЕННЯ, що ваша програма ASP.NET зможе обслуговувати. НАВАНТАЖЕННЯ . Тут технології дійсно відрізняються. ASP.NET виділяє потік для кожного запиту з його пулу потоків, і як тільки ASP.NET вичерпає всі доступні запити потоків, починає чергуватися. Якщо ви подаєте додатки "Hello World", як-от приклад @shankar, це може не мати великого значення, тому що потоки не будуть заблоковані, і ви зможете обробляти безліч запитів перед вами закінчуються нитки. Проблема з моделлю ASP.NET виникає, коли ви починаєте робити запити вводу / виводу, які блокують потік (дзвоніть до БД, робите http-запит до служби, читаєте файл з диска). Ці запити блокування означають, що ваша цінна нитка з пулу потоків нічого не робить. Чим більше ви блокуєте,
Щоб запобігти цьому блокуванню, ви використовуєте порти завершення вводу / виводу, які не вимагають утримувати нитку, поки ви чекаєте відповіді. ASP.NET підтримує це, але, на жаль, багато загальних фреймворків / бібліотек в .NET DON'T. Наприклад, ADO.NET підтримує порти завершення вводу-виводу, але Entity Framework їх не використовує. Таким чином, ви можете створити додаток ASP.NET, який має суто асинхронний режим і справляється з великим навантаженням, але більшість людей цього не робить, оскільки це не так просто, як створити синхронну та ви не зможете використовувати деякі улюблені частини рамки (як, наприклад, linkq до сутностей), якщо це зробити.
Проблема полягає в тому, що ASP.NET (і .NET Framework) були створені з метою невпевненості в асинхронному введення-виводу. .NET не хвилює, чи пишете ви синхронний чи асинхронний код, тому розробник повинен прийняти це рішення. Частина цього полягає в тому, що вважалося, що нарізка і програмування за допомогою асинхронних операцій "важкі", і .NET хотів зробити всіх щасливими (ноуби та експерти). Це стало ще складніше, тому що .NET отримав 3-4 різних схеми для асинхронізації. .NET 4.5 намагається повернутись та доопрацювати рамку .NET, щоб мати втілену модель навколо асинхронного вводу-виводу, але це може пройти деякий час, поки рамки, про які ви дбаєте, насправді її підтримують.
Дизайнери вузлів, з іншого боку, зробили впевнений вибір, що ВСІ В / О повинні бути асинхронні. Через це рішення дизайнерам вузлів також вдалося прийняти рішення про те, що кожен екземпляр вузла буде однопоточним, щоб мінімізувати комутацію потоку, і що один потік буде просто виконувати код, який був у черзі. Це може бути новий запит, це може бути зворотний виклик із запиту БД, це може бути зворотний виклик із http-запиту відпочинку, який ви зробили. Вузол намагається досягти максимальної ефективності процесора, усуваючи контекстні комутатори потоку. Оскільки вузол зробив цей впевнений вибір, що ВСІ введення / виведення є асинхронним, це також означає, що всі його рамки / доповнення підтримують цей вибір. Простіше писати додатки, які на 100% асинхронізуються у вузлі (адже вузол змушує писати програми, які є асинхронніми).
Знову ж таки, у мене немає жодних важких цифр, щоб довести той чи інший спосіб, але я думаю, що вузол виграв би конкуренцію ЗА НАВЧАННЯ для типового веб-додатка. Високооптимізований (100% асинхронний) .NET додаток може дати еквівалентному додатку node.js запустити гроші, але якщо ви взяли в середньому всі .NET і всі додатки для вузлів, середній вузол, ймовірно, обробляє більше ЗАВАНТАЖЕННЯ.
Сподіваюся, що це допомагає.
Я зробив рудиментарну перевірку працездатності між nodejs та IIS. IIS приблизно в 2,5 рази швидше, ніж nodejs, коли вимикаєте "привіт, світ!". код нижче.
моє обладнання: Dell Latitude E6510, Core i5 (двоядерний), 8 ГБ оперативної пам’яті, 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). Це дуже рудиментарний тест, і аж ніяк не переконливий. Але я вважаю, що це хороша відправна точка. Nodejs, ймовірно, швидший на інших веб-серверах, на інших платформах, але на Windows IIS є переможцем. Розробники, які хочуть перетворити свій ASP.NET MVC в nodejs, повинні зробити паузу та подумати двічі, перш ніж продовжувати.
Оновлено (17.5.2012) Tomcat (на windows), здається, бив IIS руками вниз, приблизно в 3 рази швидше, ніж IIS у вимкненні статичного html.
tomcat
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, як видається, є найшвидшим сервером у видаленні СТАТИЧНОГО HTML, НА ВІКНАХ.
Оновлено (18.05.2012) Раніше у мене було 100 000 загальних запитів із 10 000 одночасними запитами. Я збільшив його до 1 000 000 загальних запитів і 100 000 одночасних запитів. IIS виходить переможцем, який кричить, а Найдейс найгірший. Результати я описав нижче:
.
Сервери NIO (Node.js тощо), як правило, швидше, ніж BIO-сервери. (IIS тощо). Щоб підтримати мою заяву, TechEmpower - компанія, що спеціалізується на показниках веб-фреймворку . Вони дуже відкриті і мають стандартний спосіб тестування всіх кадрів.
Тести 9 раунду наразі є останніми (травень 2014 року). Існує багато перевірених ароматів IIS, але найшвидший варіант IIS, здається, позбавлений Aspnet.
Ось результати відповідей за секунду (чим вище, тим краще):
228,887
105,272
88,597
47,066
8,878
3,915
289,578
109,136
У всіх випадках Node.js, як правило, в 2 рази + швидше, ніж IIS.
Я маю згоду з Маркусом Гранстромом. Сценарій тут дуже важливий.
Якщо чесно, це здається, що ви приймаєте архітектурне рішення з високим впливом. Моя порада полягатиме в тому, щоб виділити проблеми, які викликають занепокоєння, і зробити «випічку» між усіма групами, які ви розглядаєте.
Зрештою, ви несете відповідальність за рішення, і я не думаю, що виправдання "Якийсь хлопець на Stackoverflow показав мені статтю, в якій сказано, що це буде добре" Вирішите це з вашим начальником.
Основна відмінність, що я бачу, полягає в тому, що вузол .js - це динамічна мова програмування (перевірка типу), тому типи повинні бути отриманими під час виконання. Сильно набрані мови, такі як C # .NET, теоретично набагато більший потенціал виграють боротьбу з Node .js (і PHP тощо), особливо там, де це дорогий розрахунок. До речі, .NET повинен мати кращу внутрішню взаємодію з C / C ++, ніж node .js.