httpgoreverse-proxygo-gingo-http

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


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


Solution

  • 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.