我正在开发一个用 Go 编写的 api,其主要目标是它应该尽快响应请求。我想出了使用goroutines。
我用这个命令用 wrk 测试它:
$ wrk -t1 -c200 -d1s http://127.0.0.1:8080
// this passes
...
21efef3
21efef3
21efef3
21efef3
21efef3
21efef3
21efef3
...
$ wrk -t1 -c400 -d1s http://127.0.0.1:8080
// this test fails with this error returned in go terminal
...
21efef3
21efef3
21efef3
21efef3
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x6ada46]
goroutine 2325 [running]:
github.com/gocql/gocql.(*Session).Close(0x0)
/home/mda/.local/go/src/github.com/gocql/gocql/session.go:336 +0x26
panic(0x707f40, 0x8ed650)
/usr/lib/go-1.8/src/runtime/panic.go:489 +0x2cf
github.com/gocql/gocql.(*Session).Query(0x0, 0x777d4c, 0x34, 0xc428cfd190, 0x1, 0x1, 0x0)
/home/mda/.local/go/src/github.com/gocql/gocql/session.go:294 +0x26
main.getData()
/home/mda/code/api-go/main2.go:45 +0x1f6
created by main.main.func1
/home/mda/code/api-go/main2.go:18 +0x39
exit status 2
Process finished with exit code 1
Cassandra 似乎工作正常
$ cassandra-stress read n=200000 -pop seq=1..200000 -rate threads=200 -node 127.0.0.1
Results:
Op rate : 14,090 op/s [READ: 14,090 op/s]
Partition rate : 14,090 pk/s [READ: 14,090 pk/s]
Row rate : 14,090 row/s [READ: 14,090 row/s]
Latency mean : 14.1 ms [READ: 14.1 ms]
Latency median : 9.7 ms [READ: 9.7 ms]
Latency 95th percentile : 39.4 ms [READ: 39.4 ms]
Latency 99th percentile : 72.1 ms [READ: 72.1 ms]
Latency 99.9th percentile : 218.1 ms [READ: 218.1 ms]
Latency max : 346.8 ms [READ: 346.8 ms]
Total partitions : 200,000 [READ: 200,000]
Total errors : 0 [READ: 0]
Total GC count : 14
Total GC memory : 4.346 GiB
Total GC time : 0.4 seconds
Avg GC time : 31.9 ms
StdDev GC time : 9.4 ms
Total operation time : 00:00:14
这是我的 Go 代码的简化版本:
package main
import (
"fmt"
"log"
"github.com/buaazp/fasthttprouter"
"github.com/valyala/fasthttp"
"github.com/valyala/fasthttp/reuseport"
"github.com/gocql/gocql"
)
var cluster *gocql.ClusterConfig
func main() {
router := fasthttprouter.New()
router.GET("/", func(ctx *fasthttp.RequestCtx) {
// We need this goroutine
go getData()
fmt.Fprint(ctx, "Welcome to home!")
ctx.Response.Header.ConnectionClose()
})
ln, err := reuseport.Listen("tcp4", ":8080")
if err != nil {
log.Fatalf("error in reuseport listener: %s", err)
}
if err = fasthttp.Serve(ln, router.Handler); err != nil {
log.Fatalf("error in fasthttp Server: %s", err)
}
}
func setup_cluster() {
cluster = gocql.NewCluster("127.0.0.1:9042")
cluster.Keyspace = "myKeySpace"
cluster.Consistency = gocql.One
}
func getData() {
if cluster == nil {
setup_cluster()
}
session, _ := cluster.CreateSession()
defer session.Close()
var id string
var value string
if err := session.Query(`SELECT id, ads FROM product_ads
WHERE id = ? LIMIT 1`,
"213").Consistency(gocql.One).Scan(&id, &value); err != nil {
log.Fatal(err)
}
// ... do some stuff with id & value
fmt.Println(value)
}
这是我的 go 代码和 cassandra 的进程限制,它们为不同的用户设置了相同的值:
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size unlimited unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 32768 32768 processes
Max open files 1000000 1000000 files
Max locked memory unlimited unlimited bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 31265 31265 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
你有什么建议?为什么 Go 无法创建新会话?