Повторное использование против создания нового экземпляра http.Transport в httputil.ReverseProxy

Я реализовал промежуточное ПО обратного прокси-сервера http, которое использовалось с приложением Gin framework:

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

В методе ReverseProxy я создаю экземпляр httputil.ReverseProxy, который берет transport из уже инициализированной во время init() переменной.


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)
   }
}

Итак, ВОПРОС:

правильно ли иметь один экземпляр http.Transport и повторно использовать его в httputil.ReverseProxy или мне нужно создавать новый транспорт для каждого запроса?

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)
   }
}

Какой способ лучше?

В настоящее время я повторно использую транспорт, потому что у меня прирост производительности, похоже, он использует уже созданное TCP-соединение. Но в случае высокой нагрузки я не уверен, как он будет действовать и будет ли он возвращать несвязанный ответ несвязанному клиенту?

Ссылка на исходники

🤔 А знаете ли вы, что...
Основополагающими принципами Go являются простота и читаемость кода.


54
1

Ответ:

Решено

На ваш вопрос

правильно ли иметь один экземпляр http.Transport и повторно использовать его в httputil.ReverseProxy или мне нужно создавать новый транспорт для каждого запроса?

Создание одного прокси и его повторное использование может быть правильным способом.

Более подробную информацию вы можете найти в документации Транспорт.

Transport — это реализация RoundTripper, которая поддерживает прокси-серверы HTTP, HTTPS и HTTP (для HTTP или HTTPS с CONNECT).

По умолчанию Transport кэширует подключения для повторного использования в будущем. Это может оставить много открытых соединений при доступе ко многим хостам. Этим поведением можно управлять с помощью метода CloseIdleConnections класса Transport и полей MaxIdleConnsPerHost и DisableKeepAlives.

Транспорты должны использоваться повторно, а не создаваться по мере необходимости. Транспорты безопасны для одновременного использования несколькими горутинами.