Я реализовал промежуточное ПО обратного прокси-сервера 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 являются простота и читаемость кода.
На ваш вопрос
правильно ли иметь один экземпляр http.Transport и повторно использовать его в httputil.ReverseProxy или мне нужно создавать новый транспорт для каждого запроса?
Создание одного прокси и его повторное использование может быть правильным способом.
Более подробную информацию вы можете найти в документации Транспорт.
Transport — это реализация RoundTripper, которая поддерживает прокси-серверы HTTP, HTTPS и HTTP (для HTTP или HTTPS с CONNECT).
По умолчанию Transport кэширует подключения для повторного использования в будущем. Это может оставить много открытых соединений при доступе ко многим хостам. Этим поведением можно управлять с помощью метода CloseIdleConnections класса Transport и полей MaxIdleConnsPerHost и DisableKeepAlives.
Транспорты должны использоваться повторно, а не создаваться по мере необходимости. Транспорты безопасны для одновременного использования несколькими горутинами.