IT

Node.js 및 .Net 성능

lottoking 2020. 5. 23. 09:18
반응형

Node.js 및 .Net 성능


Node.js가 빠르며 많은 양의 부하를 수용 할 수있는 것에 대해 많이 읽었습니다. 누구 든지이 프레임 워크와 다른 프레임 워크, 특히 .Net에 대한 실제 증거가 있습니까? 내가 읽은 대부분의 기사는 일화이거나 .Net과 비교할 수 없습니다.

감사


FAST 하고 많은 LOAD를 처리하는 것은 서로 다른 두 가지입니다. 초당 하나의 요청을 처리 할 때 실제로 빠른 서버는 초당 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 앱을 로드 할 수있게됩니다.

이러한 블로킹을 방지하려면 응답을 기다리는 동안 스레드를 유지할 필요가없는 I / O 완료 포트를 사용하십시오. ASP.NET은이를 지원하지만 불행히도 .NET의 많은 공통 프레임 워크 / 라이브러리를 지원합니다. 예를 들어 ADO.NET은 I / O 완료 포트를 지원하지만 Entity Framework는 해당 포트를 사용하지 않습니다. 따라서 순수하게 비동기적이고 많은 부하를 처리하는 ASP.NET 응용 프로그램을 만들 수 있지만 대부분의 사람들은 동기식 응용 프로그램을 만드는 것만 큼 쉽지 않으므로 좋아하는 부분을 사용하지 못할 수도 있습니다. 당신이하는 경우 프레임 워크 (예 : linq to entity).

문제는 ASP.NET (및 .NET Framework)이 비동기 I / O에 대해 의견이 맞지 않도록 만들어 졌다는 것입니다. .NET은 동기식 코드 나 비동기식 코드를 작성하더라도 상관하지 않으므로이 결정을 내리는 것은 개발자의 몫입니다. 비동기 작업을 통한 스레딩 및 프로그래밍이 "고난"한 것으로 생각되어 .NET이 모든 사람을 행복하게 만들려고했기 때문입니다 (누브 및 전문가). .NET이 비동기를 수행하기 위해 3-4 가지 패턴으로 끝나기 때문에 훨씬 어려워졌습니다. .NET 4.5는 돌아가서 .NET 프레임 워크를 개조하여 비동기 IO에 대한 의견이있는 모델을 만들려고하지만 관심있는 프레임 워크가 실제로이를 지원할 때까지는 시간이 걸릴 수 있습니다.

반면 노드 디자이너는 모든 I / O가 비동기 적이어야한다고 의견을 내 렸습니다. 이러한 결정으로 인해 노드 설계자들은 또한 스레드 전환을 최소화하기 위해 각 노드 인스턴스가 단일 스레드가되고 하나의 스레드가 대기열에있는 코드 만 실행하도록 결정할 수있었습니다. 새로운 요청 일 수도 있고, DB 요청의 콜백 일 수도 있고, http 나머지 요청의 콜백 일 수도 있습니다. 노드는 스레드 컨텍스트 스위치를 제거하여 CPU 효율성을 최대화하려고합니다. 노드는 ALL I / O가 비동기식이라는이 의견을 선택했기 때문에 모든 프레임 워크 / 애드온이이 선택을 지원함을 의미합니다. 노드가 100 % 비동기 인 앱을 작성하는 것이 더 쉽습니다 (노드가 비동기 인 앱을 작성해야하기 때문에).

다시 말하지만, 어떤 식 으로든 증명할 수있는 어려운 숫자는 없지만 노드가 일반적인 웹 응용 프로그램의 LOAD 경쟁에서 이길 것이라고 생각합니다. 고도로 최적화 된 (100 % 비동기) .NET 앱은 동등한 node.js 앱에 돈을 줄 수 있지만 모든 .NET 및 모든 노드 앱의 평균을 가져간 경우 평균 노드에서 더 많은 것을 처리 할 수 ​​있습니다 하중.

희망이 도움이됩니다.


nodejs와 IIS 사이에서 기본적인 성능 테스트를 수행했습니다. "hello, world!"를 제거 할 때 IIS는 nodejs보다 약 2.5 배 빠릅니다. 아래 코드.

내 하드웨어 : Dell Latitude E6510, Core i5 (이중 코어), 8GB 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

conclusion: IIS is faster than nodejs by about 2.5 times (on Windows). This is a very rudimentary test, and by no means conclusive. But I believe this is a good starting point. Nodejs is probably faster on other web servers, on other platforms, but on Windows IIS is the winner. Developers looking to convert their ASP.NET MVC to nodejs should pause and think twice before proceeding.

Updated (5/17/2012) Tomcat (on windows) seems to beat IIS hands down, about 3 times faster than IIS in dishing out static html.

tomcat

index.html at http://localhost:8080/test/
<p>hello, world!</p>

tomcat results

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

updated conclusion: i ran the benchmark program multiple times. Tomcat appears to be the fastest server in dishing out STATIC HTML, ON WINDOWS.

Updated (5/18/2012) Previously I had 100,000 total requests with 10,000 concurrent requests. I increased it to 1,000,000 total requess and 100,000 concurrent requests. IIS comes out as the screaming winner, with Nodejs fairing the worst. I have tabularized the results below:

NodeJS vs IIS vs Tomcat serving STATIC HTML on WINDOWS.


NIO servers (Node.js etc) tend to be faster than BIO servers. (IIS etc). To back my claim, TechEmpower is a company specialized on web framework benchmarks. They are very open and have a standard way of testing all framewrks.

Round 9 tests are currently the latest (May 2014). There are many IIS flavors tested, but aspnet-stripped seems to be the fastest IIS variant.

Here are the results in responses per second (higher is better):

  • JSON Serialization
    • nodejs: 228,887
    • aspnet-stripped: 105,272
  • Single Query
    • nodejs-mysql: 88,597
    • aspnet-stripped-raw: 47,066
  • Multiple Queries
    • nodejs-mysql: 8,878
    • aspnet-stripped-raw: 3,915
  • Plain Text
    • nodejs: 289,578
    • aspnet-stripped: 109,136

In all cases, Node.js tends to be 2x+ faster than IIS.


I have to agree with Marcus Granstrom the scenario is very important here.

To be honest it sounds like you’re making a high impact architectural decision. My advice would be to isolate the areas of concern and do a "bake off" between whatever stacks you are considering.

At the end of the day you are responsible for the decision and I don’t think the excuse "Some guy on Stackoverflow showed me an article that said it would be fine" Will cut it with your boss.


Main difference what I see is that node .js is dynamic programming language (type checking), so the types must be at run-time derived. The strongly typed languages like C# .NET has theoretically much more potential wins the fight against Node .js (and PHP etc.), especially where is expensive calculation. By the way the .NET should have better native interoperation with C/C++ than node .js.

참고URL : https://stackoverflow.com/questions/9290160/node-js-vs-net-performance

반응형