gpt4 book ai didi

http - go 中的 HTTP 代理

转载 作者:IT王子 更新时间:2023-10-29 01:22:24 26 4
gpt4 key购买 nike

我正在用 go 编写一个简单的代理,将 HTTP 请求中继到一个或多个后端服务器。现在我仍然只使用一台后端服务器,但性能不佳,我确定我做错了什么。可能与我将 HTTP 请求发送到另一台服务器的方式有关:如果我将对 send() 的调用注释掉,则服务器运行速度非常快,产生超过 14 krps。当调用 send() 时,性能下降到不到 1 krps,并且随着时间的推移下降得更低。这是在 MacBook Pro 上。

代码基于简单的代码示例;我已经创建了 client 并按照 docs 中的建议重用了它.使用 Apache ab 完成测试:

$ ab -n 10000 -c 10 -k "http://127.0.0.1:8080/test"

运行在端口 55455 上的后端服务器在实验之间不会改变;可以使用 Apache 或 nginx。在没有代理的情况下直接测量时,我的自定义 Web 服务器产生超过 7 krps:

$ ab -n 10000 -c 10 -k "http://127.0.0.1:55455/test"

我希望代理版本的行为与非代理版本一样好,并随着时间的推移保持性能。

完整的示例代码如下。

package main

import (
"fmt"
"log"
"net/http"
)

func main() {

tr := &http.Transport{
DisableCompression: true,
DisableKeepAlives: false,
}
client := &http.Client{Transport: tr}

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

send(r, client)
fmt.Fprintf(w, "OK")
})
log.Fatal(http.ListenAndServe(":8080", nil))
}

func send(r *http.Request, client *http.Client) int {

req, err := http.NewRequest("GET", "http://localhost:55455" + r.URL.Path, nil)
if err != nil {
log.Fatal(err)
return 0
}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
return 0
}
if resp == nil {
return 0
}
return 1
}

最终代码应该将请求发送到多个服务器并处理它们的答案,返回一个带有结果的整数。但我停留在调用电话这一步。

我做错了什么?

最佳答案

正如评论所建议的,您应该返回(和处理)类型错误而不是整数,并且重申一下,不要使用 AB。对我来说最突出的是

  1. 您应该在Transport 中设置MaxIdleConnsPerHost。这表示有多少连接将持续存在(保持事件状态),即使它们此时无事可做。
  2. 必须阅读并关闭响应正文才能将其返回到池中。

...
resp, err := client.Do(req)
if err != nil {
return err
}
responseBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
defer resp.Body.Close()
...

关于http - go 中的 HTTP 代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25477442/

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