这是 hgfischer 写的 Nginx 和 Go 作web 服务的压力测试,主要对下面不同的使用方式做比较:
- Go HTTP standalone (as the control group)
- Nginx proxy to Go HTTP
- Nginx fastcgi to Go TCP FastCGI
- Nginx fastcgi to Go Unix Socket FastCGI
Nginx 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
user www-data;
worker_processes auto;
worker_rlimit_nofile 200000;
pid /var/run/nginx.pid;
events {
worker_connections 10000;
use epoll;
multi_accept on;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 300;
keepalive_requests 10000;
types_hash_max_size 2048;
open_file_cache max=200000 inactive=300s;
open_file_cache_valid 300s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
server_tokens off;
dav_methods off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log combined;
error_log /var/log/nginx/error.log warn;
gzip off;
gzip_vary off;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*.conf;
}
虚拟主机配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
upstream go_http {
server 127.0.0.1:8080;
keepalive 300;
}
server {
listen 80;
server_name go.http;
access_log off;
error_log /dev/null crit;
location / {
proxy_pass http://go_http;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
upstream go_fcgi_tcp {
server 127.0.0.1:9001;
keepalive 300;
}
server {
listen 80;
server_name go.fcgi.tcp;
access_log off;
error_log /dev/null crit;
location / {
include fastcgi_params;
fastcgi_keep_conn on;
fastcgi_pass go_fcgi_tcp;
}
}
upstream go_fcgi_unix {
server unix:/tmp/go.sock;
keepalive 300;
}
server {
listen 80;
server_name go.fcgi.unix;
access_log off;
error_log /dev/null crit;
location / {
include fastcgi_params;
fastcgi_keep_conn on;
fastcgi_pass go_fcgi_unix;
}
}
测试用的go 代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package main
import (
"fmt"
"log"
"net"
"net/http"
"net/http/fcgi"
"os"
"os/signal"
"syscall"
)
var (
abort bool
)
const (
SOCK = "/tmp/go.sock"
)
type Server struct {
}
func (s Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
body := "Hello World\n"
// Try to keep the same amount of headers
w.Header().Set("Server", "gophr")
w.Header().Set("Connection", "keep-alive")
w.Header().Set("Content-Type", "text/plain")
w.Header().Set("Content-Length", fmt.Sprint(len(body)))
fmt.Fprint(w, body)
}
func main() {
sigchan := make(chan os.Signal, 1)
signal.Notify(sigchan, os.Interrupt)
signal.Notify(sigchan, syscall.SIGTERM)
server := Server{}
go func() {
http.Handle("/", server)
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
}()
go func() {
tcp, err := net.Listen("tcp", ":9001")
if err != nil {
log.Fatal(err)
}
fcgi.Serve(tcp, server)
}()
go func() {
unix, err := net.Listen("unix", SOCK)
if err != nil {
log.Fatal(err)
}
fcgi.Serve(unix, server)
}()
<-sigchan
if err := os.Remove(SOCK); err != nil {
log.Fatal(err)
}
}
GOMAXPROCS = 1
时比较结果
Go standalone
1
2
3
4
5
6
7
8
9
# wrk -t100 -c5000 -d30s http://127.0.0.1:8080/
Running 30s test @ http://127.0.0.1:8080/
100 threads and 5000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 116.96ms 17.76ms 173.96ms 85.31%
Req/Sec 429.16 49.20 589.00 69.44%
1281567 requests in 29.98s, 215.11MB read
Requests/sec: 42745.15
Transfer/sec: 7.17MB
Nginx + Go through HTTP
1
2
3
4
5
6
7
8
9
# wrk -t100 -c5000 -d30s http://go.http/
Running 30s test @ http://go.http/
100 threads and 5000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 124.57ms 18.26ms 209.70ms 80.17%
Req/Sec 406.29 56.94 0.87k 89.41%
1198450 requests in 29.97s, 201.16MB read
Requests/sec: 39991.57
Transfer/sec: 6.71MB
Nginx + Go through FastCGI TCP
1
2
3
4
5
6
7
8
9
10
# wrk -t100 -c5000 -d30s http://go.fcgi.tcp/
Running 30s test @ http://go.fcgi.tcp/
100 threads and 5000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 514.57ms 119.80ms 1.21s 71.85%
Req/Sec 97.18 22.56 263.00 79.59%
287416 requests in 30.00s, 48.24MB read
Socket errors: connect 0, read 0, write 0, timeout 661
Requests/sec: 9580.75
Transfer/sec: 1.61MB
Nginx + Go through FastCGI Unix Socket
1
2
3
4
5
6
7
8
9
10
# wrk -t100 -c5000 -d30s http://go.fcgi.unix/
Running 30s test @ http://go.fcgi.unix/
100 threads and 5000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 425.64ms 80.53ms 925.03ms 76.88%
Req/Sec 117.03 22.13 255.00 81.30%
350162 requests in 30.00s, 58.77MB read
Socket errors: connect 0, read 0, write 0, timeout 210
Requests/sec: 11670.72
Transfer/sec: 1.96MB
原文 《Benchmarking Nginx with Go》
本文网址: https://golangnote.com/topic/69.html 转摘请注明来源