Kết quả không mong đợi của bài kiểm tra hiệu năng của node.js và ASP.NET Core


177

Tôi đang làm một bài kiểm tra căng thẳng nhanh chóng trên hai (loại) xin chào các dự án thế giới được viết bằng . Cả hai đều chạy trong chế độ sản xuất và không có bộ ghi chép kèm theo. Kết quả thật đáng kinh ngạc! Lõi ASP.NET vượt trội hơn ứng dụng node.js ngay cả sau khi thực hiện một số công việc bổ sung trong khi ứng dụng node.js chỉ hiển thị chế độ xem.

Ứng dụng 1: http://localhost:3000/nodejs node.js

Sử dụng : node.js, công cụ kết xuất nhanh và vash.

ứng dụng nodejs

Mã trong điểm cuối này là

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

Như bạn có thể thấy, không có gì ngoài việc gửi ngày hiện tại thông qua timebiến đến chế độ xem.

Ứng dụng 2: http://localhost:5000/aspnet-core asp.net core

Sử dụng : ASP.NET Core, nhắm mục tiêu mẫu mặc địnhdnxcore50

Tuy nhiên, ứng dụng này làm một cái gì đó ngoài việc chỉ hiển thị một trang có ngày trên đó. Nó tạo ra 5 đoạn văn bản ngẫu nhiên khác nhau. Về mặt lý thuyết, điều này sẽ làm cho ứng dụng này nặng hơn một chút so với ứng dụng nodejs.

ứng dụng cốt lõi asp.net

Đây là phương thức hành động khiến trang này

[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();
}

Kết quả kiểm tra căng thẳng

Kết quả kiểm tra căng thẳng ứng dụng Node.js

Cập nhật: Theo đề xuất của Gorgi Kosev

Sử dụng npm install -g recluster-cli && NODE_ENV=production recluster-cli app.js 8

kiểm tra nodejs 2

Kết quả kiểm tra căng thẳng ứng dụng ASP.NET Core

kết quả kiểm tra căng thẳng cốt lõi asp.net

Không thể tin vào mắt mình! Không thể đúng là trong bài kiểm tra cơ bản này, lõi asp.net nhanh hơn nhiều so với nodejs. Dĩ nhiên đây không phải là số liệu duy nhất được sử dụng để đo lường hiệu suất giữa hai công nghệ web này, nhưng tôi tự hỏi tôi đang làm gì sai trong phía node.js? .

Là một nhà phát triển asp.net chuyên nghiệp và muốn điều chỉnh node.js trong các dự án cá nhân, đây là một loại khiến tôi thất vọng - vì tôi hơi hoang tưởng về hiệu suất. Tôi nghĩ rằng node.js nhanh hơn lõi asp.net (nói chung - như đã thấy trong các điểm chuẩn khác nhau) Tôi chỉ muốn chứng minh điều đó với chính mình (để khuyến khích bản thân thích nghi với node.js).

Vui lòng trả lời trong nhận xét nếu bạn muốn tôi bao gồm nhiều đoạn mã hơn.

Cập nhật: Phân phối thời gian của ứng dụng .NET Core

phân phối thời gian ứng dụng aspnetcore

Phản hồi của máy chủ

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

52
"Tôi luôn nghĩ rằng node.js nhanh hơn lõi asp.net" - Tôi tò mò tại sao bạn nghĩ vậy? Tôi chưa thấy bất kỳ điểm chuẩn nào hỗ trợ điều này (lý do chính tôi đã nghe thấy khi áp dụng node.js là "dễ sử dụng" và "thời gian phát triển / lặp lại nhanh hơn")
UnholySheep

7
@UnholySheep Đó là tất cả những gì tôi nghe được về người bạn đời, tôi cũng nghe thấy nó "dễ sử dụng" và "phát triển nhanh hơn", nói chung từ những người sử dụng không bao giờ làm việc trong ASP.NET, đặc biệt là trong VisualStudio. Tôi không khoe khoang về bất kỳ công nghệ nào - nhưng đây là mô hình tôi nhận thấy.
không xác định

3
Câu hỏi ở đây là gì? Nếu nó hợp lý: Có. techempower.com/benchmark/ từ .... Ngoài ra, cập nhật chuỗi công cụ của bạn là Dnxcore50 đã lỗi thời ít nhất một hoặc hai năm.
Thomas

2
@Tony sử dụng mô-đun cụm NodeJs sinh ra nhiều công nhân đang làm và chia sẻ tải của quy trình chính đang lắng nghe trên một quy trình. Nó chỉ tránh việc phải thiết lập nhiều ứng dụng trên các cổng khác nhau. Ngoài ra, nếu nodeJs đang chạy trong chế độ cụm thì sẽ có cùng số lượng Asp.Net WebApplecting chạy trong IIS trên các cổng khác và chia sẻ tải giữa chúng thông qua một số bộ cân bằng tải, sau đó sẽ là so sánh đúng.
Vipresh

36
Node.js tuyệt vời cho nhiều thứ, nhưng tốc độ thô cho mỗi yêu cầu không phải là một trong số đó. Những gì nó nổi trội là trở thành một nhà môi giới cho các hoạt động I / O, bởi vì điều vòng lặp sự kiện không chặn, mà khi Node mới và sáng bóng, là một vấn đề lớn. Tất nhiên, kể từ đó, các ngôn ngữ và khung khác đã bắt kịp, vì vậy, trong .NET, chúng tôi có Thư viện song song tác vụ và I / O không đồng bộ và không đồng bộ / đang chờ. Cái mà Node không nổi trội là các hoạt động gắn với CPU như kết xuất trang, bởi vì đó là JavaScript đơn luồng.
Đánh dấu Rendle

Câu trả lời:


188

Như nhiều người khác đã ám chỉ, sự so sánh thiếu bối cảnh.
Tại thời điểm phát hành, cách tiếp cận không đồng bộ của node.js là một cuộc cách mạng. Kể từ đó, các ngôn ngữ và khung web khác đã áp dụng các phương pháp tiếp cận mà họ sử dụng chính thống.

Để hiểu sự khác biệt có nghĩa là gì, bạn cần mô phỏng một yêu cầu chặn đại diện cho một số khối lượng công việc IO, chẳng hạn như một yêu cầu cơ sở dữ liệu. Trong một hệ thống theo yêu cầu của luồng, điều này sẽ làm cạn kiệt luồng và các yêu cầu mới sẽ được đưa vào hàng đợi chờ một luồng có sẵn.
Với các khung không chặn-io, điều này không xảy ra.

Hãy xem xét máy chủ node.js này đợi 1 giây trước khi phản hồi

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

Bây giờ, hãy ném 100 đồng thời vào đó, trong 10 giây. Vì vậy, chúng tôi mong đợi khoảng 1000 yêu cầu để hoàn thành.

$ 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

Như bạn có thể thấy chúng tôi vào sân bóng với 922 đã hoàn thành.

Bây giờ hãy xem xét mã asp.net sau đây, được viết như thể async / await chưa được hỗ trợ, do đó, chúng tôi quay lại thời kỳ khởi chạy của 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! Ở đây chúng ta thấy giới hạn của luồng. Bằng cách điều chỉnh nó, chúng tôi có thể nhận được nhiều yêu cầu đồng thời hơn, nhưng với chi phí nhiều tài nguyên máy chủ hơn.

Đối với các khối lượng công việc ràng buộc IO này, việc di chuyển để tránh chặn các luồng xử lý là rất kịch tính.

Bây giờ chúng ta hãy mang nó đến ngày hôm nay, nơi mà ảnh hưởng đó đã gợn sóng trong ngành và cho phép dotnet tận dụng những cải tiến của nó.

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

Không có gì ngạc nhiên ở đây, bây giờ chúng tôi khớp với node.js.

Vậy, tất cả điều này có ý nghĩa gì?

Ấn tượng của bạn rằng node.js là "nhanh nhất" đến từ thời đại chúng ta không còn sống. Thêm vào đó không bao giờ là nút / js / v8 "nhanh", đó là họ đã phá vỡ chuỗi yêu cầu theo yêu cầu mô hình. Mọi người khác đã bắt kịp.

Nếu mục tiêu của bạn là xử lý nhanh nhất các yêu cầu đơn lẻ, thì hãy nhìn vào các điểm chuẩn nghiêm túc thay vì tự thực hiện. Nhưng nếu thay vào đó, những gì bạn muốn chỉ đơn giản là thứ gì đó đạt đến tiêu chuẩn hiện đại, thì hãy chọn bất kỳ ngôn ngữ nào bạn thích và đảm bảo rằng bạn không chặn các luồng đó.

Tuyên bố miễn trừ trách nhiệm: Tất cả các mã được viết và các bài kiểm tra chạy trên MacBook Air cũ trong một buổi sáng Chủ nhật buồn ngủ. Vui lòng lấy mã và dùng thử trên Windows hoặc điều chỉnh theo nhu cầu của bạn - https://github.com/csurdy/nodejs-vs-aspnetcore


35
NodeJs không bao giờ là duy nhất, mô hình Thread per request cũng tồn tại trong Asp.Net trước khi nodejs được giới thiệu. Tất cả các phương thức I / O có 2 phiên bản được đồng bộ hóa và Không đồng bộ được cung cấp bởi Framework, các phương thức ASYNC của chúng kết thúc bằng từ khóa "Async" cho ví dụ. methodNameAsync
Vipresh

Như một ví dụ. Bạn có thể tham khảo bài viết này liên quan đến các hoạt động DB có từ năm 2008 codedigest.com/Articles/ADO/
mẹo

4
"Các cách tiếp cận họ đã sử dụng chủ đạo" - một vài điều độc đáo, họ đặt vấn đề trước một đối tượng rộng lớn hơn nhiều. Có một cách tiếp cận có sẵn, và làm cho nó trở thành một nguyên tắc cốt lõi là hai điều rất khác nhau.
Chris Sainty

4
Câu trả lời tốt nhất ở đây. Giai đoạn = Stage.
Narvalex

3
@LeeBrindley Tôi không đồng ý, điều này không cố gắng chứng minh thông lượng tối đa của phần cứng nhất định, nó thể hiện sự khác biệt giữa chặn và không chặn. Nếu bạn muốn so sánh thông lượng thô, tôi liên kết với techempower.
Chris Sainty

14

Các Node Framework như Express và Koa có một chi phí khủng. Nút "thô" nhanh hơn đáng kể.

Tôi đã không thử nó, nhưng có một khung mới hơn rất gần với hiệu suất của nút "Raw": https://github.com/aerojs/aero

(xem điểm chuẩn trên trang đó)

cập nhật: Dưới đây là một số số liệu: https://github.com/blitzprog/webserver-benchmark

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

Như bạn có thể thấy, các tổng phí trong các khung công tác node.js phổ biến nhất là RẤT đáng kể!


5
các con số để làm gì? Càng cao càng tốt?
Iamisti
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.