对比 node/go/java 等语言 web 服务器性能
2019年06月23日
性能测试命令
1wrk -t2 -c100 -d10 --latency http://localhost:9000
以上命令表示:开启 2 个线程,保持 100 个 http 连接,持续 10s 时间,最终打印延迟统计信息。
测试环境
型号名称: MacBook Pro 型号标识符: MacBookPro14,1 处理器名称: Intel Core i5 处理器速度: 2.3 GHz 处理器数目: 1 核总数: 2 L2 缓存(每个核): 256 KB L3 缓存: 4 MB 超线程技术: 已启用 内存: 8 GB
总体来说逻辑核心数为 4 个。
node.js
1const http = require('http'); 2 3http 4 .createServer((req, res) => { 5 res.end('hello world\n'); 6 }) 7 .listen(9000, () => { 8 console.log('start web at port 9000'); 9 });
用 node index.js 的方式启动程序后的测试结果(一个进程):
Running 10s test @ http://localhost:9000
2 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 3.60ms 1.14ms 26.97ms 92.89%
Req/Sec 14.15k 2.05k 16.11k 81.00%
Latency Distribution
50% 3.26ms
75% 3.63ms
90% 4.41ms
99% 7.84ms
281573 requests in 10.01s, 30.08MB read
Requests/sec: 28138.64
Transfer/sec: 3.01MB
50%请求延时在3.26毫秒。
用 pm2 start index.js -i 4 的方式启动程序后的测试结果(四个进程):
Running 10s test @ http://localhost:9000
2 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 4.50ms 7.57ms 144.58ms 91.30%
Req/Sec 19.97k 4.84k 41.89k 82.00%
Latency Distribution
50% 1.46ms
75% 4.97ms
90% 11.02ms
99% 35.93ms
398020 requests in 10.03s, 42.51MB read
Requests/sec: 39685.38
Transfer/sec: 4.24MB
好像开启四个进程的收益没有那么大。且标准差变大了。
go
1package main 2 3import ( 4 "fmt" 5 "log" 6 "net/http" 7) 8 9func main() { 10 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 11 fmt.Fprintln(w, "hello world") 12 }) 13 fmt.Println("start web at port 9001") 14 log.Fatal(http.ListenAndServe("localhost:9001", nil)) 15}
Running 10s test @ http://localhost:9001
2 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 6.41ms 14.11ms 229.69ms 89.26%
Req/Sec 27.53k 15.85k 57.81k 64.36%
Latency Distribution
50% 1.01ms
75% 5.01ms
90% 21.58ms
99% 53.90ms
540458 requests in 10.04s, 66.49MB read
Requests/sec: 53843.81
Transfer/sec: 6.62MB
从数据来看好像不是很稳定,请求延时的标准差较大。不过相对于node的数据来说较好。
spring boot
1package hello; 2 3import org.springframework.web.bind.annotation.RequestMapping; 4import org.springframework.web.bind.annotation.RestController; 5 6/** 7 * HomeController 8 */ 9@RestController 10public class HomeController { 11 12 @RequestMapping("/") 13 public String home() { 14 return "hello world\n"; 15 } 16}
Running 10s test @ http://localhost:8080
2 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 2.18ms 1.66ms 29.98ms 86.57%
Req/Sec 18.07k 3.70k 25.67k 65.50%
Latency Distribution
50% 1.94ms
75% 2.56ms
90% 3.66ms
99% 8.46ms
362340 requests in 10.09s, 43.60MB read
Requests/sec: 35921.99
Transfer/sec: 4.32MB
虽然每秒请求数没有node和go多,但是很稳定,性能也还可以。
内存占用情况
1ps aux
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
liqiang 53065 0.0 0.8 5008640 65284 ?? S 9:16上午 0:19.54 node /Users/liqiang/Desktop/api_performance_test/node/index.js
liqiang 53064 0.0 0.6 5008564 52056 ?? S 9:16上午 0:19.75 node /Users/liqiang/Desktop/api_performance_test/node/index.js
liqiang 53063 0.0 0.6 5008824 48980 ?? S 9:16上午 0:19.66 node /Users/liqiang/Desktop/api_performance_test/node/index.js
liqiang 53062 0.0 0.7 5009236 61088 ?? S 9:16上午 0:19.70 node /Users/liqiang/Desktop/api_performance_test/node/index.js
liqiang 52006 0.0 0.2 4416020 12956 s001 S+ 9:08上午 2:52.73 ./main
liqiang 55990 0.0 8.9 8016876 749292 s003 S+ 11:57上午 1:11.11 /usr/bin/java -jar build/libs/gs-rest-service-0.1.0.jar
运行时 golang 占用内存最小,且性能最好,仅占用 13M。 node 开了四个进程,每个进程占用 60M,总 240M。 java 就比较厉害了,占用了 750M 内存,同等内存下可以开几十个 go 程序了。