Reusing vs Creating new instance of http.Transport in httputil.ReverseProxy

huangapple go评论81阅读模式
英文:

Reusing vs Creating new instance of http.Transport in httputil.ReverseProxy

问题

我已经实现了与Gin框架应用程序一起使用的HTTP反向代理中间件:

app := gin.New()
app.Use(proxy.ReverseProxy("127.0.0.1:8008"))  // 在这里我附加了ReverseProxy中间件

ReverseProxy方法中,我创建了httputil.ReverseProxy的实例,该实例从在init()期间初始化的变量中获取transport

var transport *http.Transport

func init() {  // 在这里创建Transport的实例
   transport = &http.Transport{
     // 一些参数
   }
}

func ReverseProxy(targetServer string) gin.HandlerFunc {
   return func(c *gin.Context) {

      proxy := &httputil.ReverseProxy{
         Transport: transport,             // 在这里重用Transport的实例
         // 一些参数
      }
      proxy.ServeHTTP(c.Writer, c.Request)
   }
}

所以问题是:

httputil.ReverseProxy中拥有一个http.Transport的实例并重用它是否正确,还是我需要在每个请求中创建新的transport?

func ReverseProxy(targetServer string) gin.HandlerFunc {
   return func(c *gin.Context) {

      // 在这里创建Transport的实例
      transport = &http.Transport{
        // 一些参数
      }

      proxy := &httputil.ReverseProxy{
         Transport: transport,            // 在这里使用新的Transport实例
         // 一些参数
      }
      proxy.ServeHTTP(c.Writer, c.Request)
   }
}

哪种方式更好?

我目前重用transport,因为它可以提高性能,似乎它使用了已经创建的TCP连接。
但是在高负载情况下,我不确定它的行为如何,它是否会将不相关的响应返回给不相关的客户端?

源代码链接

英文:

I've implemented http reverse proxy middleware which used with Gin framework app:

app := gin.New()
app.Use(proxy.ReverseProxy("127.0.0.1:8008"))  // HERE I'm attaching ReverseProxy middleware

In ReverseProxy method I'm creating instance of httputil.ReverseProxy which takes transport from already initialized during init() variable.


var transport *http.Transport

func init() {  // HERE creating instance of Transport
   transport = &http.Transport{
     // some params
   }
}

func ReverseProxy(targetServer string) gin.HandlerFunc {
   return func(c *gin.Context) {

      proxy := &httputil.ReverseProxy{
         Transport: transport,             // HERE reusing instance of Transport
         // some params
      }
      proxy.ServeHTTP(c.Writer, c.Request)
   }
}

So QUESTION:

is it correct to have one instance of http.Transport and reuse it in httputil.ReverseProxy or I've to create new transport on every request?

func ReverseProxy(targetServer string) gin.HandlerFunc {
   return func(c *gin.Context) {

      // HERE creating instance of Transport
      transport = &http.Transport{
        // some params
      }

      proxy := &httputil.ReverseProxy{
         Transport: transport,            // HERE using NEW instance of Transport
         // some params
      }
      proxy.ServeHTTP(c.Writer, c.Request)
   }
}

Which way is best?

I currently reuse transport cause I've got performance boost, seems like it uses already created tcp connection.
But in case of high load I'm not sure how it will act and will it return unrelated response to unrelated client?

Link to sources

答案1

得分: 3

对于你的问题:

> 在 httputil.ReverseProxy 中创建一个 http.Transport 实例并重用它是否正确,还是每个请求都必须创建新的 transport?

创建一个代理并重用它可能是正确的方式。

你可以在 Transport 文档中找到更多详细信息。

> Transport 是 RoundTripper 的一个实现,支持 HTTP、HTTPS 和 HTTP 代理(用于 HTTP 或 HTTPS 的 CONNECT)。

> 默认情况下,Transport 会缓存连接以供将来重用。当访问多个主机时,这可能会导致许多打开的连接。可以使用 Transport 的 CloseIdleConnections 方法以及 MaxIdleConnsPerHost 和 DisableKeepAlives 字段来管理此行为。

> 应该重用 Transport 而不是根据需要创建。Transport 可以安全地被多个 goroutine 并发使用。

英文:

For your question

> is it correct to have one instance of http.Transport and reuse it in httputil.ReverseProxy or I've to create new transport on every request?

Creating one proxy and reusing it could be the correct way.

You could find more details per the Transport documentation.

> Transport is an implementation of RoundTripper that supports HTTP, HTTPS, and HTTP proxies (for either HTTP or HTTPS with CONNECT).

> By default, Transport caches connections for future re-use. This may leave many open connections when accessing many hosts. This behavior can be managed using Transport's CloseIdleConnections method and the MaxIdleConnsPerHost and DisableKeepAlives fields.

> Transports should be reused instead of created as needed. Transports are safe for concurrent use by multiple goroutines.

huangapple
  • 本文由 发表于 2022年11月13日 07:26:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/74417340.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定