开发者社区> 问答> 正文

golang proxy timeout的问题

golang proxy timeout的问题

需求: 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,还是我的使用不当?

展开
收起
问问小秘 2020-01-09 16:34:23 2110 0
1 条回答
写回答
取消 提交回答
  • 你给的 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 来让空闲连接超时

    2020-01-09 18:22:55
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
阿里开发者手册-Golang专题 立即下载
Golang 微服务在腾讯游戏用户运营领域的探索及实践 立即下载
RocketMQ Client-GO 介绍 立即下载