[C#] node.js와 ASP.NET Core 성능 테스트의 예기치 않은 결과

나는 두 개의 (kinda) hello world 프로젝트에서 빠른 스트레스 테스트를하고 있습니다. . 둘 다 프로덕션 모드에서 실행되고 로거가 첨부되지 않았습니다. 결과는 놀랍습니다! ASP.NET 코어는 추가 작업을 한 후에도 node.js 앱보다 성능이 뛰어나며 node.js 앱은 뷰를 렌더링합니다.

앱 1 : http://localhost:3000/nodejs node.js

사용 : node.js, 표현 및 vash 렌더링 엔진.

nodejs 앱

이 엔드 포인트의 코드는

router.get('/', function(req, res, next) {
  var vm = {
    title: 'Express',
    time: new Date()
  }
  res.render('index', vm);
});

보시다시피, time변수를 통해 현재 날짜를 뷰로 보내는 것 외에는 아무것도하지 않습니다 .

앱 2 : http://localhost:5000/aspnet-core asp.net core

사용 : ASP.NET Core, 기본 템플릿 타겟팅dnxcore50

그러나이 응용 프로그램은 날짜가있는 페이지를 렌더링하는 것 이외의 작업을 수행합니다. 다양한 임의의 텍스트로 5 개의 단락을 생성합니다. 이것은 이론적으로 nodejs 앱보다 조금 더 무겁게 만들어야합니다.

asp.net 핵심 앱

이 페이지를 렌더링하는 동작 방법은 다음과 같습니다.

[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
[Route("aspnet-core")]
public IActionResult Index()
{
    var sb = new StringBuilder(1024);
    GenerateParagraphs(5, sb);

    ViewData["Message"] = sb.ToString();
    return View();
}

스트레스 테스트 결과

Node.js 앱 스트레스 테스트 결과

업데이트 : Gorgi Kosev의 제안에 따라

사용 npm install -g recluster-cli && NODE_ENV=production recluster-cli app.js 8

nodejs 테스트 2

ASP.NET Core App 스트레스 테스트 결과

asp.net 코어 스트레스 테스트 결과

내 눈을 믿을 수 없어! 이 기본 테스트에서 asp.net 코어가 nodejs보다 훨씬 빠르다는 것은 사실이 아닙니다. 물론이 두 웹 기술 간의 성능을 측정하는 데 사용되는 유일한 메트릭은 아니지만 node.js 측에서 내가 뭘 잘못하고 있는지 궁금 합니다. .

전문적인 asp.net 개발자이며 개인 프로젝트에 node.js를 적용하고 싶을 때 성능에 약간의 편집증이 있기 때문에 이런 일이 발생합니다. node.js가 asp.net 코어보다 빠르다고 생각했습니다 (일반적으로 다른 벤치 마크에서 볼 수 있듯이). 나는 그것을 직접 증명하고 싶습니다 (노드 .js를 적응시키는 것을 장려하기 위해).

더 많은 코드 스 니펫을 포함 시키려면 의견에 회신하십시오.

업데이트 :
.NET Core 앱의 시간 배포

aspnetcore 앱 시간 배포

서버 응답

HTTP/1.1 200 OK
Cache-Control: no-store,no-cache
Date: Fri, 12 May 2017 07:46:56 GMT
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
Server: Kestrel



답변

다른 많은 사람들이 언급했듯이 비교에는 컨텍스트가 없습니다.
릴리스 당시 node.js의 비동기 접근 방식은 혁신적이었습니다. 그 이후로 다른 언어와 웹 프레임 워크가 주류를 이루는 접근 방식을 채택하고 있습니다.

차이점이 무엇인지 이해하려면 데이터베이스 요청과 같은 일부 IO 워크로드를 나타내는 차단 요청을 시뮬레이션해야합니다. 요청 당 스레드 시스템에서는 스레드 풀이 소모되고 사용 가능한 스레드를 기다리는 새 요청이 큐에 배치됩니다.
non-blocking-io 프레임 워크에서는 이런 일이 발생하지 않습니다.

응답하기 전에 1 초 동안 대기하는이 node.js 서버를 고려하십시오.

const server = http.createServer((req, res) => {
  setTimeout(() => {
    res.statusCode = 200;
    res.end();
  }, 1000);
});

이제 10 초 동안 100 개의 동시 연결을 던져 봅시다. 따라서 약 1000 건의 요청이 완료 될 것으로 예상합니다.

$ wrk -t100 -c100 -d10s http://localhost:8000
Running 10s test @ http://localhost:8000
  100 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.01s    10.14ms   1.16s    99.57%
    Req/Sec     0.13      0.34     1.00     86.77%
  922 requests in 10.09s, 89.14KB read
Requests/sec:     91.34
Transfer/sec:      8.83KB

보시다시피 우리는 922가 완성 된 야구장에 도착합니다.

이제 async / await가 아직 지원되지 않는 것처럼 작성된 다음 asp.net 코드를 고려하여 node.js 시작 시대로 거슬러 올라갑니다.

app.Run((context) =>
{
    Thread.Sleep(1000);
    context.Response.StatusCode = 200;
    return Task.CompletedTask;
});

$ wrk -t100 -c100 -d10s http://localhost:5000
Running 10s test @ http://localhost:5000
  100 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.08s    74.62ms   1.15s   100.00%
    Req/Sec     0.00      0.00     0.00    100.00%
  62 requests in 10.07s, 5.57KB read
  Socket errors: connect 0, read 0, write 0, timeout 54
Requests/sec:      6.16
Transfer/sec:     566.51B

62! 여기서 우리는 스레드 풀의 한계를 봅니다. 이를 조정하면 더 많은 동시 요청이 발생할 수 있지만 더 많은 서버 리소스가 필요합니다.

이러한 IO 바운드 워크로드의 경우 처리 스레드 차단을 피하기위한 이동이 대단했습니다.

이제 그 영향력을 업계에 파급시키고 닷넷이 개선을 활용할 수있게 해주는 오늘로 가져 갑시다.

app.Run(async (context) =>
{
    await Task.Delay(1000);
    context.Response.StatusCode = 200;
});

$ wrk -t100 -c100 -d10s http://localhost:5000
Running 10s test @ http://localhost:5000
  100 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.01s    19.84ms   1.16s    98.26%
    Req/Sec     0.12      0.32     1.00     88.06%
  921 requests in 10.09s, 82.75KB read
Requests/sec:     91.28
Transfer/sec:      8.20KB

놀랍지 않게 이제 우리는 node.js와 일치합니다.

이 모든 것이 무엇을 의미합니까?

node.js가 “가장 빠르다”는 인상은 우리가 더 이상 살고 있지 않은 시대에서 온 것입니다. “빠른”것은 결코 node / js / v8이 아니라는 것입니다. 모델. 다른 사람들은 따라 잡고 있었다.

목표가 단일 요청을 처리하는 가장 빠른 처리 인 경우 자체 롤링 대신 심각한 벤치 마크 를 살펴보십시오 . 그러나 대신 원하는 것이 단순히 현대 표준으로 확장되는 것이라면 원하는 언어로 이동하여 스레드를 차단하지 않는지 확인하십시오.

면책 조항 : 졸린 일요일 아침에 노화 된 MacBook Air에서 작성된 모든 코드와 테스트가 실행됩니다. 코드를 가져 와서 Windows에서 사용해 보거나 필요에 맞게 조정하십시오-https: //github.com/csainty/nodejs-vs-aspnetcore


답변

Express 및 Koa와 같은 노드 프레임 워크에는 끔찍한 오버 헤드가 있습니다. “원시”노드가 훨씬 빠릅니다.

나는 그것을 시도하지는 않았지만 “Raw”노드 성능에 매우 가까운 새로운 프레임 워크가 있습니다 : https://github.com/aerojs/aero

(해당 페이지의 벤치 마크 참조)

업데이트 : 다음 수치는 다음과 같습니다. https://github.com/blitzprog/webserver-benchmarks

Node:
    31336.78
    31940.29
Aero:
    29922.20
    27738.14
Restify:
    19403.99
    19744.61
Express:
    19020.79
    18937.67
Koa:
    16182.02
    16631.97
Koala:
    5806.04
    6111.47
Hapi:
    497.56
    500.00

보다시피 가장 인기있는 node.js 프레임 워크의 오버 헤드는 매우 중요합니다!


답변