location / {
include fastcgi_params;
fastcgi_keep_conn on;
fastcgi_pass go_fcgi_unix;
}
}
Go源码
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)
}
}
为公平起见,所有的请求必需大小相同。
$ curl -sI :8080/
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 12
Content-Type: text/plain
Server: gophr
Date: Sun, 15 Dec 2013 14:59:14 GMT
$ curl -sI :8080/ | wc -c
141
$ curl -sI
HTTP/1.1 200 OK
Server: nginx
Date: Sun, 15 Dec 2013 14:59:31 GMT
Content-Type: text/plain
Content-Length: 12
Connection: keep-alive
$ curl -sI | wc -c
141
$ curl -sI
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 12
Connection: keep-alive
Date: Sun, 15 Dec 2013 14:59:40 GMT
Server: gophr
$ curl -sI | wc -c
141
$ curl -sI
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 12
Connection: keep-alive
Date: Sun, 15 Dec 2013 15:00:15 GMT
Server: gophr
$ curl -sI | wc -c
141
使用sysctl配置内核
配置Nginx
配置Nginx vhosts
用www-data启动服务
运行基准测试
基准测试 GOMAXPROCS = 1 Go standalone# wrk -t100 -c5000 -d30s :8080/
Running 30s test @ :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
# wrk -t100 -c5000 -d30s
Running 30s test @
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
# wrk -t100 -c5000 -d30s
Running 30s test @
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