需求:
golang实现proxy来做到前端请求某个url后落到proxy上,proxy再发起请求到backend server, 然后为了性能问题, 我需要考虑超时后放弃后端返回,以及提醒http client超时(504)
我的思路:
target, err := url.Parse(backend)
if err != nil {
fmt.Printf("backend %s parse errr : %v\n", backend, err)
}
reserveProxy := httputil.NewSingleHostReverseProxy(target)
reserveProxy.Transport = Transport{cfg}
c.Request.Host = target.Host
c.Request.URL.Path = newReqpath
reserveProxy.ServeHTTP(c.Writer, c.Request)
proxyTransport := http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 3 * time.Second,
KeepAlive: 30 * time.Second,
Deadline: time.Now().Add(3 * time.Second),
}).DialContext,
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
return proxyTransport.RoundTrip(r)
我试图使用golang自带的reserveproxy
来做proxy,并且利用transport
的timeout
,但是整个请求完全没有超时的作用(模拟一个接口20s,整个proxy就20s返回给http client)
寻找思路:
github issue
stackoverflow
发现有人和我遇到同样的问题,但是没有解决
所以这是不是golang的一个bug,还是我的使用不当?
有一定的思考不错
你给的 github issue 其实已经回答了你的问题,可能你没有认真看:
net.Dialer
中的配置都是配置 TCP 的,其中 Timeout 指的是 TCP connect 时的超时时间,KeepAlive 指的是 TCP 连接无数据可以保持的时间,等等而你想要的是无论是 TCP connect 还是 HTTP response,只要 3s 无数据就要中断操作
所以,你配置的 Timeout 3s 可以针对 TCP connect 有用;除此之外,你还可以将 KeepAlive 配置成 3s,来处理 HTTP 无响应的情况(这可能有用,也可能没用,取决于你的操作系统)
此外,你还可以配置 http.Transport 中的 IdleConnTimeout 来让空闲连接超时