ASP.NET Core 性能对比评测(ASP.NET,Python,Java,NodeJS)

前言

性能是我们日常生活中经常接触到的一个词语,更好的性能意味着能给我们带来更好的用户体检。比如我们在购买手机、显卡、CPU 等的时候,可能会更加的关注于这样指标,所以本篇就来做一个性能评测。

性能也一直是我们开发人员一直追求的一个目标,我们在做语言选择,平台选择,架构选择的过程中都需要在性能之间做衡量。

同样性能对 .NET Core 团队来说也是至关重要的,一项新技术的诞生,除了对生产力的提高,还有技术团队对性能的追求。

今天,我们就来做一个对比测试,来看看微软的这样新技术性能到底怎么样,俗话说的好:“是骡子是马,拉出来溜溜”。

下面让我开始吧。

目录

测试目标

在测试之前,我们必须要明确我们本次测试想达到的一个目标。本次测试主要是测试应用程序的一个吞吐量。其中 QPS,并发数,响应时间是我们衡量吞吐量的几个重要指标。

以下是本次对比测试的任务目标:

编号 对比方 系统环境 宿主环境 测试目标
1 ASP.NET Core vs ASP.NET Core Windows Kestrel vs IIS 相同平台不同宿主间性能差距
2 ASP.NET Core vs ASP.NET Windows IIS vs IIS 相同平台相同宿主不同框架间性能差距
3 ASP.NET Core vs ASP.NET Windows Kestrel vs IIS 相同平台不同宿主不同框架间性能差距
4 ASP.NET Core vs Python Django Linux Kestrel vs uwsgi 相同平台不同语言不同宿主不同框架间性能差距
5 ASP.NET Core vs Java Servlet Linux Kestrel vs Tomcat 相同平台不同语言不同宿主不同框架间性能差距
6-1 ASP.NET Core vs NodeJS Express Linux Kestrel vs self host 相同平台不同语言不同宿主不同框架间性能差距
6-2 ASP.NET Core vs NodeJS Koa Linux Kestrel vs self host 相同平台不同语言不同宿主不同框架间性能差距

测试工具

工欲善其事,必先利其器。

首先我们需要一个压力测试工具,本次我们使用 wrk,有关于 wrk 的介绍和使用,请查看我的 这篇博客

然后我们需要一个性能监控工具,因为 wrk 已经会给我们输出吞吐量相关指标,所以我们只需要一个监控 CPU,内存等的工具即可。本次我们使用 Windows 自带的性能监视器。

Windows 性能监视器的打开方式:开始-->运行-->perfmon
PS: 在下面的监视器图中如果你发现 cpu 并没有 100%,那是因为使用的虚拟机占用了一部分 cpu,所以计算方式应该是虚拟机的 cpu 使用量 + 物理机 cpu 使用量。

环境准备

既然做测试,首先肯定是具有相同的运行环境,以下是本次测试使用到的软件和硬件环境。

  • 软硬件环境
名称 操作系统 职责 CPU 核心数 内存
物理机器 1 Windows 10 RS1 Web Server && 负载生成 Intel Core i5-4590 4 16G
虚拟机器 2 Ubuntu Server 16.04 Web Server Intel Core i5-4590 2 1G
虚拟机器 3 Nano Server Web Server Intel Core i5-4590 2 1G

其中 虚拟机器2 为 “物理机器 1” 使用 win 10 的 Hyper-v 技术搭建的一个虚拟机,所以有几个指标对于本次测试至关重要。

image

虚拟机设置为了 2 个虚拟核心,以便于在压力测试的过程中利用到多核特性。其中的虚拟机保留百分比,需要设置为 100%,来分配两个物理 cpu 所有资源给它。占综系统资源百分比设置为 50,也就是说虚拟机最多利用本地 50% 的 CPU 资源,虚拟机限制设置为 100。

  • 源代码

AspNet 在 GitHub 有一个开源的性能测试项目叫benchmarks,之前新闻中 23 倍的性能也是出自于本测试项目, 为了客观,本次测试并不使用该项目,所有项目均我们自己新建,并且使用当前流行的框架, 为了排除代码因素的干扰,我们使用最简单的 Hello World!。

如果你觉得本代码不够客观公正,欢迎在 GitHub 上 Fork 本项目,修改后给我提交 PR,我会重新进行测试,并且更新本博客。

GitHub: https://github.com/yuleyule66/AspNetCoreBenchmarksCompare

开始测试

wkr 命令参数:

wrk -t 2 -c 50 -d 20 --latency http://xxx

因为已经分配了 2 个核心给虚拟机使用,所以开的是双线程。使用这个参数是我经过多次测试,得到的一个最佳的模拟效果。

1 - ASP.NET Core vs ASP.NET Core(Kestrel vs IIS)

ASP.NET Core

  • 环境:物理机器 1
  • OS:Windows 10 RS 1
  • Host:Kestrel
wrk -t 2 -c 50 -d 20 --latency http://localhost:5000

Running 20s test @ http://localhost:5000
2 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 5.49ms 21.72ms 358.18ms 98.99%
Req/Sec 23.28k 1.98k 27.48k 92.13%
Latency Distribution
50% 0.00us
75% 6.87ms
90% 12.76ms
99% 28.58ms
913567 requests in 20.02s, 115.00MB read
Requests/sec: 45636.43
Transfer/sec: 5.74MB


ASP.NET Core

  • 环境:物理机器 1
  • OS:Windows 10 RS 1
  • Host:IIS 10.0
wrk -t 2 -c 50 -d 20 --latency http://localhost:5001

Running 20s test @ http://localhost:5001
2 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 5.30ms 5.81ms 22.24ms 76.75%
Req/Sec 7.61k 455.21 8.12k 90.00%
Latency Distribution
50% 3.14ms
75% 9.02ms
90% 15.62ms
99% 17.17ms
302880 requests in 20.02s, 44.77MB read
Requests/sec: 15130.97
Transfer/sec: 2.24MB


总结

QPS(Kestrel):45636.43
QPS(IIS):15130.97

这个结果难免令人诧异,程序部署在 IIS 上和使用 Kestrel 竟然差别如此之大,我们知道实际上即便部署在 IIS 上,实际上内部还是调用的 Kestrel,但是测试结果告诉了我们答案。可能是由于 IIS 进一步的 http 封装导致的吧,毕竟 IIS 提供了那么多的其他功能。

以下是 Windows 的性能监视器,两个的曲线图差不多我就放一个了:
image

  • 红色:CPU 使用率
  • 蓝色:内存使用率

2 - ASP.NET Core vs ASP.NET(IIS vs IIS)

ASP.NET Core

  • 环境:物理机器 1
  • OS:Windows 10 RS
  • Host:IIS
wrk -t 2 -c 50 -d 20 --latency http://localhost:5001

Running 20s test @ http://localhost:5001
2 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 5.30ms 5.81ms 22.24ms 76.75%
Req/Sec 7.61k 455.21 8.12k 90.00%
Latency Distribution
50% 3.14ms
75% 9.02ms
90% 15.62ms
99% 17.17ms
302880 requests in 20.02s, 44.77MB read
Requests/sec: 15130.97
Transfer/sec: 2.24MB


ASP.NET

  • 环境:物理机器 1
  • OS:Windows 10 RS
  • Host:IIS
  • .NET Framework 4.6 + MVC5
wrk -t 2 -c 50 -d 20 --latency http://localhost:10280

Running 20s test @ http://localhost:10280
2 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 4.94ms 5.58ms 22.82ms 80.90%
Req/Sec 9.10k 444.04 9.42k 95.00%
Latency Distribution
50% 3.00ms
75% 10.10ms
90% 13.57ms
99% 16.45ms
362177 requests in 20.00s, 89.80MB read
Requests/sec: 18104.50
Transfer/sec: 4.49MB


总结

QPS(ASP.NET Core + IIS):15130.97
QPS(ASP.NET + IIS):18104.50

看到这个结果的时候,其实我还是有一点小惊讶的,不仅仅是因为 ASP.NET 跑出了 1.8K QPS 这样的成绩,而是通过Stdev可以看出,ASP.NET 在应对高请求高并发的时候,还是相当的稳定的。这个结果说明了,在同样 Windows+IIS 环境中,ASP.NET 是具有优势和竞争力的,可以预见 ASP.NET 应该还不会淘汰的太快。

Windows 性能图我就不上了,基本上和上面一样 CPU 100% 的使用率。

3 - ASP.NET Core vs ASP.NET(Kestrel vs IIS)

ASP.NET Core

  • 环境:物理机器 1
  • OS:Windows 10 RS 1
  • Host:Kestrel
wrk -t 2 -c 50 -d 20 --latency http://localhost:5000

Running 20s test @ http://localhost:5000
2 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 5.49ms 21.72ms 358.18ms 98.99%
Req/Sec 23.28k 1.98k 27.48k 92.13%
Latency Distribution
50% 0.00us
75% 6.87ms
90% 12.76ms
99% 28.58ms
913567 requests in 20.02s, 115.00MB read
Requests/sec: 45636.43
Transfer/sec: 5.74MB


ASP.NET

  • 环境:物理机器 1
  • OS:Windows 10 RS
  • Host:IIS
  • .NET Framework 4.6 + MVC5
wrk -t 2 -c 50 -d 20 --latency http://localhost:10280

Running 20s test @ http://localhost:10280
2 threads and 50 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 4.94ms 5.58ms 22.82ms 80.90%
Req/Sec 9.10k 444.04 9.42k 95.00%
Latency Distribution
50% 3.00ms
75% 10.10ms
90% 13.57ms
99% 16.45ms
362177 requests in 20.00s, 89.80MB read
Requests/sec: 18104.50
Transfer/sec: 4.49MB


总结

QPS(ASP.NET Core + Kestrel):45636.43

QPS(ASP.NET + IIS):18104.50

这个结果应该是在预料之中的,大概是 3 倍的性能差距吧。但是我觉得和之前微软宣传的 23 倍的性能,是有很大差距的。

4 - ASP.NET Core vs Python Django

注意,以下我们开始使用到虚拟机器 2 了,我们要在 Windows 性能监控器里面查看 CPU 使用率,还需要再添加 2 个计数器。

物理处理器 \Hyper-V Hypervisor Logical Processor(*) \ %Total Run Time

虚拟处理器 \Hyper-V Hypervisor Virtual Processor(*) \ %Guest Run Time

ASP.NET Core

  • 环境:虚拟机器 2
  • OS:Linux
  • Host:Kestrel
wrk -t 2 -c 50 -d 20 --latency http://192.168.2.48:5000/
Running 20s test @ http://192.168.2.48:5000/
  2 threads and 50 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     4.39ms    5.33ms  33.05ms   77.20%
    Req/Sec    13.43k     1.32k   17.95k    74.75%
  Latency Distribution
     50%    2.00ms
     75%    8.15ms
     90%   13.75ms
     99%   15.80ms
  534787 requests in 20.01s, 67.32MB read
Requests/sec:  26730.83
Transfer/sec:      3.37MB

image


Python Django

  • 环境:虚拟机器 2
  • OS:Linux
  • Host:uwsgi
  • Python 2.7.12 + Django 1.10.2

服务端宿主运行命令:

sudo uwsgi --http :8000 --file HelloWorldWebApp/wsgi.py --processes=2 --threads==2 --daemonize=/var/log/django.log

结果:

wrk -t 2 -c 50 -d 20 --latency http://192.168.2.48:8000
Running 20s test @ http://192.168.2.48:8000
  2 threads and 50 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    23.40ms   12.23ms  78.13ms   74.81%
    Req/Sec   792.64    143.13     1.25k    67.10%
  Latency Distribution
     50%   21.16ms
     75%   31.25ms
     90%   38.26ms
     99%   53.75ms
  31591 requests in 20.09s, 3.01MB read
  Socket errors: connect 0, read 31591, write 0, timeout 0
Requests/sec:   1572.64
Transfer/sec:    153.67KB

image


总结

QPS(ASP.NET Core + Kestrel):26730.83

QPS(Python Django + Kestrel ):1572.64

不知道是我运行的方式不对还是怎么,这个差距还是蛮大的,大概是 17 倍的差距。看来 Python Web 在做针对于做大请求并发情况下,还是弱了一点。

5 - ASP.NET Core vs Java Servlet

C# 和 JAVA 一直是两大阵营的开发人员喜欢讨论的话题,为了避免有阵营偏见,JAVA 的源代码是我委托我们一个 JAVA 同事编写的,并且委托由他部署的,并且已经交代了他避免使用 jsp,由 Servlet 直接输出。

ASP.NET Core

  • 环境:虚拟机器 2
  • OS:Linux
  • Host:Kestrel
wrk -t 2 -c 50 -d 20 --latency http://192.168.2.48:5000/
Running 20s test @ http://192.168.2.48:5000/
  2 threads and 50 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     4.39ms    5.33ms  33.05ms   77.20%
    Req/Sec    13.43k     1.32k   17.95k    74.75%
  Latency Distribution
     50%    2.00ms
     75%    8.15ms
     90%   13.75ms
     99%   15.80ms
  534787 requests in 20.01s, 67.32MB read
Requests/sec:  26730.83
Transfer/sec:      3.37MB

image


Java Servlet

  • 环境:虚拟机器 2
  • OS:Linux
  • Host:Tomcat 7.0 + jdk 1.7
wrk -t 2 -c 50 -d 20 --latency http://192.168.2.48:8080/j2eeWebApp/hello
Running 20s test @ http://192.168.2.48:8080/j2eeWebApp/hello
  2 threads and 50 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     4.93ms    6.17ms  68.17ms   81.53%
    Req/Sec     9.22k     1.01k   14.06k    70.50%
  Latency Distribution
     50%    1.75ms
     75%    9.91ms
     90%   14.39ms
     99%   22.10ms
  367733 requests in 20.05s, 93.70MB read
Requests/sec:  18338.73
Transfer/sec:      4.67MB

image


总结

QPS(ASP.NET Core + Kestrel):26730.83

QPS(Java Servlet + Tomcat):18338.73

通过这个结果我们可以看出,在性能上 ASP.NET Core 已经超越了 Java。不说太多了,怕被喷...

6 - ASP.NET Core vs NodeJS

ASP.NET Core

  • 环境:虚拟机器 2
  • OS:Linux
  • Host:Kestrel
wrk -t 2 -c 50 -d 20 --latency http://192.168.2.48:5000/
Running 20s test @ http://192.168.2.48:5000/
  2 threads and 50 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     4.39ms    5.33ms  33.05ms   77.20%
    Req/Sec    13.43k     1.32k   17.95k    74.75%
  Latency Distribution
     50%    2.00ms
     75%    8.15ms
     90%   13.75ms
     99%   15.80ms
  534787 requests in 20.01s, 67.32MB read
Requests/sec:  26730.83
Transfer/sec:      3.37MB

NodeJS

  • 环境:虚拟机器 2
  • OS:Linux
  • Host:self host
wrk -t 2 -c 50 -d 20 --latency http://192.168.2.48:1337
Running 20s test @ http://192.168.2.48:1337
  2 threads and 50 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     4.40ms    5.23ms  31.25ms   79.47%
    Req/Sec    10.32k     0.88k   11.37k    90.25%
  Latency Distribution
     50%    2.08ms
     75%    8.32ms
     90%   13.19ms
     99%   15.93ms
  410902 requests in 20.02s, 61.13MB read
Requests/sec:  20522.89
Transfer/sec:      3.05MB

image

********更新 1:NodeJS 添加 Web 框架

Express 框架,cluster 模式

wrk -t 2 -c 30 -d 20 --latency http://192.168.2.48:1337
Running 20s test @ http://192.168.2.48:1337
  2 threads and 30 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.97ms    1.45ms  32.23ms   83.97%
    Req/Sec     7.83k     0.90k    8.82k    91.50%
  Latency Distribution
     50%    2.00ms
     75%    2.50ms
     90%    3.50ms
     99%    6.00ms
  311896 requests in 20.01s, 66.03MB read
Requests/sec:  15583.99
Transfer/sec:      3.30MB

Koa 框架,cluster 模式

wrk -t 2 -c 30 -d 20 --latency http://192.168.2.48:1337
Running 20s test @ http://192.168.2.48:1337
  2 threads and 30 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.74ms    0.86ms  13.59ms   86.65%
    Req/Sec     8.79k   804.39     9.98k    87.75%
  Latency Distribution
     50%    1.99ms
     75%    2.00ms
     90%    2.96ms
     99%    4.83ms
  349856 requests in 20.02s, 53.38MB read
Requests/sec:  17478.73
Transfer/sec:      2.67MB

从测试结果可以看出,Koa 框架性能略高于 Express 框架。

***End


总结

QPS(ASP.NET Core + Kestrel):26730.83

QPS(NodeJS):20522.89 (非 cluster 模式)
QPS(NodeJS Express):15583.99 (cluster 模式)
QPS(NodeJS Koa):17478.73 (cluster 模式)

这个结果着实让我吃了一惊,NodeJS 性能竟然如此惊人,比 JAVA 要快 10%。作为一个解释性语言这个性能可以说达到了极致,虽然在测试之前知道 NodeJS 采用的是异步 IO,但还是被测试结果震惊了。

=== 更新 1=

NodeJS 在加入了 Web 框架之后,性能仍然不弱。


不知道是不是因为 NodeJS 没有经过什么 Web 框架,直接输出的结果。所以我需要再加测一个 ASP.NET Core 通过中间件直接输入结果的性能,这次我要使用微软的测试项目 benchmarks。

wrk -t 2 -c 50 -d 20 --latency http://192.168.2.48:5000/plaintext
Running 20s test @ http://192.168.2.48:5000/plaintext
  2 threads and 50 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     3.69ms    5.03ms  18.30ms   80.38%
    Req/Sec    25.06k     4.14k   29.19k    83.33%
  Latency Distribution
     50%  806.00us
     75%    6.82ms
     90%   12.62ms
     99%   15.63ms
  1002476 requests in 20.10s, 126.20MB read
Requests/sec:  49874.57
Transfer/sec:      6.28MB

My God !!!

总结

以下是测试结果的汇总统计:

编号 对比方 系统环境 宿主环境 测试结果(QPS)
1 ASP.NET Core vs ASP.NET Core Windows Kestrel vs IIS 45.6k vs 15.2k
2 ASP.NET Core vs ASP.NET Windows IIS vs IIS 15.2k vs 18.2k
3 ASP.NET Core vs ASP.NET Windows Kestrel vs IIS 45.6k vs 18.2k
4 ASP.NET Core vs Python Django Linux Kestrel vs uwsgi 26.7k vs 1.57k
5 ASP.NET Core vs Java Servlet Linux Kestrel vs Tomcat 26.7k vs 18.3k
6-1 ASP.NET Core vs NodeJS Express Linux Kestrel vs self host 26.7k vs 15.6k
6-2 ASP.NET Core vs NodeJS Koa Linux Kestrel vs self host 26.7k vs 17.5k

image

作为微软的下一代 ASP.NET 框架,ASP.NET Core 没有让我们失望,通过本次测试,我们大概对 ASP.NET Core 的性能心里有底了。一个圈子的良好发展需要社区的共同参与,也希望大家共同为.NET Core 社区贡献自己的力量,同时也希望看到本篇文章的 CTOs 们以后在平台和框架选择的过程中考虑一下 ASP.NET Core,因为她真的很优秀。

如果你觉得本篇博客对您有帮助的话,感谢您的【推荐】,如果你对.NET Core 感兴趣可以关注我,我会定期在博客分享关于.NET Core 的学习心得。


== 更新 1 :2016-10-17 感谢园友“幻天芒” 关于 NodeJS 的贡献

有园友反应 NodeJS 项目没有使用 web mvc 框架,所以特更新,同时感谢 "幻天芒" 在 github 向 nodeJS 项目提交的 PR。

1、添加 node 多核 cpu cluster 模式
2、添加 node koa框架和express框架测试

更新测试结果。


== 更新 2 :2016-10-19 添加 ASP.NET Core 在 Windows Nano Server 的测试结果

环境:虚拟机器 3,和 Linux 硬件一样

wrk -t 2 -c 30 -d 20 --latency http://192.168.2.52:8000
Running 20s test @ http://192.168.2.52:8000
  2 threads and 30 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.08ms  709.98us  31.25ms   77.30%
    Req/Sec    13.98k     1.38k   15.80k    87.75%
  Latency Distribution
     50%    1.00ms
     75%    1.03ms
     90%    2.00ms
     99%    3.45ms
  556354 requests in 20.03s, 70.04MB read
Requests/sec:  27780.50
Transfer/sec:      3.50MB

这个测试结果和微软的测试结果是一致的,Nano Server 大概比在 Linux 上高出 5-10% 的性能。


======== 更新 3 :2016-12-30 添加 WebListener 测试 ======

WebListener 是基于 Http.sys 实现的非跨平台只能运行于 Windows 的一个 web 服务器,其目的我觉得是为了替代 iis 的性能不足问题。

引用自 QQ 群 Lyrics:我的理解是这样的,Kestrel 是跨平台的,定义了一套通用的 feature,然而目前在 windows 平台上,Kestrel 所具备的 feature 并没有 http.sys 提供的那么强大,为了使老系统能顺利迁移到 core 上面,微软不得已搞了一个能支持所有 http.sys 的 web server,就是 weblistener, weblistener 能完整的利用 http.sys 的特性,在 windows 上功能完整。

测试结果:

Windows ASP.NET Core Kestrel :35.5k

Windows ASP.NET Core WebListener:27.9k

Kestrl 大概比 WebListener 高出 5-10% 的性能。


本文地址:http://www.cnblogs.com/savorboard/p/dotnet-benchmarks.html
作者博客:Savorboard
欢迎转载,请在明显位置给出出处及链接