Ubuntu 14.04
apt-get install nginx apache2-utils
然后vi /etc/nginx/sites-enabled/default
是这些内容:
server {
listen 80 default_server;
location / {
return 200 "Ok";
}
}
service nginx restart
跑步:
ab -c 500 -k -n 100000 127.0.0.1/
我得到的结果:
Percentage of the requests served within a certain time (ms)
50% 0
66% 0
75% 0
80% 0
90% 0
95% 0
98% 14
99% 489
100% 3065 (longest request)
好的,所以我很快就得到了大多数响应(这是预料之中的),但大约 1%(近 1000 个请求)的响应非常慢。(0.5 秒 - 3 秒)
为什么会发生这种情况?如何找到问题的根源?我猜是 kernel/sysctl,但如何确切地找出问题所在?
更新1
我尝试ab
用替换siege
,结果是一样的。
siege -c 500 -r 200 -b 127.0.0.1/
....
Concurrency: 240.67
Successful transactions: 100000
Failed transactions: 0
Longest transaction: 1.50
Shortest transaction: 0.00
我尝试改变一些变量,nginx
并在每次改变后重新启动服务器并重新运行ab
。
worker_processes 10;
worker_connections 7680;
multi_accept on;
events { use select; }
events { use poll; }
events { use epoll; }
我sysctl
每次都尝试调整并重新运行测试:
net.core.somaxconn=5120 # including listen directive backlog in nginx
net.core.netdev_max_backlog=5120
我将打开文件的数量增加到 5000000 并重新运行测试。
我尝试了一些其他的 tcp 拥塞控制方法,每次都重新运行测试。
sysctl -w net.ipv4.tcp_congestion_control=hybla
sysctl -w net.ipv4.tcp_congestion_control=illinois
sysctl -w net.ipv4.tcp_congestion_control=lp
sysctl -w net.ipv4.tcp_congestion_control=probe
sysctl -w net.ipv4.tcp_congestion_control=scalable
sysctl -w net.ipv4.tcp_congestion_control=vegas
sysctl -w net.ipv4.tcp_congestion_control=veno
sysctl -w net.ipv4.tcp_congestion_control=westwood
sysctl -w net.ipv4.tcp_congestion_control=yeah
我尝试了更多的 sysctl 变量,并每次重新运行测试。
sysctl -w net.core.rmem_max=67108864
sysctl -w net.ipv4.tcp_rmem='4096 87380 33554432'
sysctl -w net.ipv4.tcp_wmem='4096 65536 33554432'
sysctl -w net.core.netdev_max_backlog=30000
sysctl -w net.ipv4.tcp_congestion_control=htcp
sysctl -w net.ipv4.tcp_mtu_probing=1
sysctl -w net.core.rmem_max=134217728
sysctl -w net.core.wmem_max=134217728
sysctl -w net.ipv4.tcp_rmem='4096 87380 67108864'
sysctl -w net.ipv4.tcp_wmem='4096 65536 67108864'
sysctl -w net.core.netdev_max_backlog=250000
sysctl -w net.ipv4.tcp_congestion_control=htcp
sysctl -w net.ipv4.tcp_mtu_probing=1
最后,我下载golang
并编译了服务器,并ab
针对这个基本服务器进行了测试——一切都一样。
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "OK")
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
go run test.go
似乎没有什么能够影响这 1%。
更新2
好吧,这可能和 CPU 饱和度有关。在 16 核 GCE 机器上,效果要好得多,而且不太明显。原始测试是在 1 核 Digital Ocean 实例上进行的。
更新3
是的,一定是 CPU 出了问题。对 4 核 GCE 没有影响。(已添加为答案)
答案1
答案似乎是——CPU 不够
4 核 GCE
Percentage of the requests served within a certain time (ms)
50% 8
66% 12
75% 16
80% 17
90% 24
95% 28
98% 35
99% 41
100% 63 (longest request)
1 核 GCE
Percentage of the requests served within a certain time (ms)
50% 0
66% 0
75% 0
80% 0
90% 0
95% 0
98% 4
99% 509
100% 3597 (longest request)