gpt4 book ai didi

go - Redigo:在 Apache 负载测试中出现错误

转载 作者:数据小太阳 更新时间:2023-10-29 03:05:49 25 4
gpt4 key购买 nike

我正在使用库 redigo 将我的 go 程序连接到 redis。当我运行一个请求时,我得到了正确的结果。但是在负载测试中,使用 apache 基准测试工具,它在以下情况下起作用:

ab -n 1000 -k -c 10 -p post.txt -T application/x-www-form-urlencoded http://localhost:8084/abcd

但是当请求是:

ab -n 1000 -k -c 15 -p post.txt -T application/x-www-form-urlencoded http://localhost:8084/abcd

我收到错误:

panic: dial tcp :6379: too many open files

这是我的代码:

func newPool() *redis.Pool {
return &redis.Pool{
MaxIdle: 80, // max number of connections
Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp", ":6379")
if err != nil {
panic(err.Error())
}
return c, err
},
// If Wait is true and the pool is at the MaxActive limit, then Get() waits
// for a connection to be returned to the pool before returning
Wait: true,
}
}

var pool = newPool()

func checkError(err error) {
if err != nil {
log.Fatal(err)
}
}

func func1(pool *redis.Pool, id int) string {
c := pool.Get()
defer c.Close()
m, err := redis.String(c.Do("HGET", "key", id))
checkError(err)
return m
}

func func2(pool *redis.Pool, string_ids []string) chan string {
c := make(chan string)
var ids []int
var temp int
for _, v := range string_ids {
temp, _ = strconv.Atoi(v)
ids = append(ids, temp)
}
go func() {
var wg sync.WaitGroup
wg.Add(len(ids))
for _, v := range ids {
go func(id int) {
defer wg.Done()
c <- func1(pool, id)
}(v)
}
wg.Wait()
close(c)
}()
return c
}
func getReq(w http.ResponseWriter, req *http.Request) {
err := req.ParseForm()
checkError(err)
ids := req.Form["ids[]"]
for v := range func2(pool, ids) {
fmt.Println(v)
}
}

func main() {
http.HandleFunc("/abcd", getReq)

log.Fatal(http.ListenAndServe(":8084", nil))
}

如何使用 apache 基准测试工具处理至少 40 个并发请求。

注意:我没有在我的 redis conf 文件中更改任何内容

我在运行 apache 基准测试工具时收到以下响应。仅完成 15 个请求。

$ ab -n 1000 -k -c 15 -p post.txt -T application/x-www-form-urlencoded http://localhost:8084/abcd
This is ApacheBench, Version 2.3 <$Revision: 1528965 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
apr_socket_recv: Connection refused (111)
Total of 15 requests completed

最佳答案

要立即解决问题,请在您的 redis.Pool 上设置 MaxActive,您在评论中提到了它,但您自己没有设置。

但从根本上说,您不应该为每个 id 查找分派(dispatch) goroutine。您的最大可能并发将是 (客户端连接数)x(请求中的 id 数),每个都可以打开一个新的 redis 连接。让单个 redis 连接串行读取每个 ids 会更快、更高效。这里不需要任何额外的并发性,从处理程序串行执行所有操作,并且当 redis 仅对字符串键进行操作时,不要将字符串转换为整数。

func getReq(w http.ResponseWriter, req *http.Request) {
err := req.ParseForm()
checkError(err)

c := pool.Get()
defer c.Close()

for _, id := range req.Form["ids[]"] {
m, err := redis.String(c.Do("HGET", "key", id))
checkError(err)
fmt.Println(id)
}
}

如果你想进一步优化这个,你可以使用pipelines减少到 redis 服务器的往返次数。

for _, id := range req.Form["ids[]"] {
c.Send("HGET", "key", id))
}
c.Flush()
values, err := redis.Strings(c.Receive())
checkError(err)
...

关于go - Redigo:在 Apache 负载测试中出现错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39244845/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com