【发布时间】:2021-10-02 10:15:59
【问题描述】:
我正在构建一个面向性能的 REST-API。 骨架是用 go-swagger 构建的。
API 有 3 毫秒的响应时间,并且在单次使用中成功,而响应时间仅需要 0.5 毫秒 - 0.8 毫秒。对 redis 进行了两次调用。
这是池的启动方式:
func createPool(server string) *redis.Pool {
return &redis.Pool{
MaxIdle: 500,
MaxActive: 10000,
IdleTimeout: 5 * time.Second,
//MaxConnLifetime: 1800 * time.Microsecond,
Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp", server)
if err != nil {
return nil, err
}
return c, err
},
TestOnBorrow: func(c redis.Conn, t time.Time) error {
if time.Since(t) < (3 * time.Second) {
return nil
}
_, err := c.Do("PING")
if err != nil {
}
return err
},
}
而且这里是唯一使用泳池的地方:
func GetValue(params Params) []int64 {
timeNow := time.Now()
conn := data.Pool.Get()
value1 := Foo(conn)
value2 := Bar(value1 , conn)
conn.Close()
defer Log(value1, value2)
return value2}
所以基本上一开始我从池中获得一个连接,用于两个 redis 请求,然后关闭它。我以前使用过defer conn.Close(),正如文档中所述,它也不起作用。 vm.overcommit_memory=1 和 net.core.somaxconn=512 已在服务器上设置。
单独使用 API 没有问题。 当处于压力之下时,例如每秒 4000 个请求,它会在最初的 10 秒内工作,然后变得非常慢并且无法及时响应(开始时规定的 3 毫秒)。
当我检查 ActiveCount 和 IdleCount 时,值介于 2 和 5 之间,并且始终相同。 MaxActive 值为 10.000 是否应该有更多的连接?还是我遗漏了一些关键设置?
【问题讨论】:
-
测试过程中测试应用使用了多少并发连接?您在测试期间是否在测试应用程序和被测应用程序之间使用保持连接?测试期间 CPU 和内存的表现如何?
defer Log(value1, value2)是做什么的? -
Active/Idle-Count 最多只能达到 12。我在有和没有保持活动连接的情况下对其进行了测试 - 没有任何改变。服务器的 CPU 和内存低于 30%,所以我看不出有问题。这只是一个记录请求内容的函数。对吗,服务器端没有关闭连接,而是存储在对客户端的响应中?当客户端没有正确关闭连接时,服务器还会等待吗?
-
您描述的症状表明某种类型的资源在一段时间后耗尽。在此类测试中,由于未使用 keep-alive 而导致大量连接处于 TIME_WAIT 状态的问题并不少见(请使用
netstat检查)。如果将日志发送到某些服务,则日志记录也可能存在问题。您是否尝试过没有Log功能的测试。我不明白关于存储连接以响应客户端的问题。 -
您也可以使用pprof 来查看您的 goroutine,当您观察到已处理请求的下降时。
-
感谢您的帮助。问题与 redis 无关,但您的建议有助于解决问题!
标签: redis redigo go-swagger