springboot VS go VS netty http请求压测
0结果
ubuntu 24, 1 cpu 2 core 4 threads
go version go1.24.0 linux/amd64 |
openjdk version "1.8.0_452" spring boot 2.1.8.RELEASE |
差几倍 |
netty 4.1.100.final epoll |
|
并发 | 1000 | 1000 | ||
loop | 50 | 50 | ||
QPS | 4100-4300 | 2800-2900 | 2450 | |
VIRT虚拟内存 | 1.24GB | 3.6GB | 3倍 | |
RES物理内存 | 20MB | 241MB | 10倍 | |
用户空间cpu耗时 | 4秒 | 74秒 | 20倍 | 22秒 |
内核空间cpu耗时 | 3秒 | 6.4秒 | 10秒 | |
上下文切换 | 32 k | 176 k | 5倍 | |
CPU cycle | 12 billion | 150 billion | 12.5倍 | 55 billion |
stalled cpu cycle frontend | 10 billion | 118 billion | 12 倍 | 44 billion |
cache reference | 184 million | 2.3 billion | 12.5倍 | 983 million |
一级缓存数据 | 1.16 billion | 22.5 billion | 19.4倍 | |
一级缓存指令 | 284 million / 22% | 1.91 billion / 22% | 7倍 | |
三级缓存 | 54 million | 1.1 billion | 20倍 | |
内存访问 | 220 k | 959 k | 5倍 |
1 java
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
@RestController("")
public class UserController {
@GetMapping("hello")
public String toAction(String content){
return "hello";
}
perf stat -e task-clock -e cycles -e stalled-cycles-frontend -e stalled-cycles-backend -e cache-references -e cache-misses -e L1-dcache-loads -e L1-dcache-load-misses -e L1-dcache-stores -e L1-dcache-store-misses -e L1-dcache-prefetches -e L1-dcache-prefetch-misses -e L1-icache-load-misses -e LLC-loads -e LLC-load-misses -e cpu-migrations -e mem-loads -e context-switches java -jar -Xmx100m -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false -Djava.rmi.server.hostname=192.168.1.63 -Dcom.sun.management.jmxremote.port=8888 -Dcom.sun.management.jmxremote.rmi.port=8888 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Xloggc:logs/gc.log -jar Delete-1.0.0.jar
cs:
2 go
package main
import (
"fmt"
"net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
fmt.Fprintf(w, "Hello")
}
func main() {
http.HandleFunc("/hello", helloHandler)
fmt.Println("Server is listening on port 8080")
if err := http.ListenAndServe(":8080", nil); err != nil {
fmt.Printf("Failed to start server: %s\n", err)
}
}
run:
perf stat -e task-clock -e cycles -e stalled-cycles-frontend -e stalled-cycles-backend -e cache-references -e cache-misses -e L1-dcache-loads -e L1-dcache-load-misses -e L1-dcache-stores -e L1-dcache-store-misses -e L1-dcache-prefetches -e L1-dcache-prefetch-misses -e L1-icache-load-misses -e LLC-loads -e LLC-load-misses -e cpu-migrations -e mem-loads -e context-switches go run fir.go
cs:
VmPeak:当前进程运行过程中占用内存的峰值。 VmSize:当前进程正在占用的内存大小,是VmLib, VmExe, VmData, 和 VmStk的总和。 VmLck:当前进程已经锁住的物理内存的大小,锁住的物理内存不能交换到硬盘。 VmPin:固定内存的大小,是固定在特定页框位置的锁定内存,固定的页面既不能被移除物理内存,也不能被内核在RAM中移动。 VmHWM:进程分配到的物理内存的峰值。 VmRSS:程序正在使用的物理内存大小,RSS实际使用量=RSSAnon+RssFile+RssShmem。 RssAnon:匿名页占用物理内存大小。 RssFile:文件页占用物理内存大小。 RssShmem:共享内存物理内存大小。 VmDate:进程数据段大小。 VmStk:进程堆栈段大小。 VmExe:进程代码段大小。 VmLib:进程所使用的lib库大小。 VmPTE:进程页表占用内存大小。 VmSwap:进程占用swap交换分区大小。