HttpClient прекращает повторное использование соединений после изменения балансировки нагрузки
У меня есть клиент, который подключается к настройке облачного сервера - экземпляр HAProxy (один из нескольких, определяемых балансировщиком нагрузки), который затем перенаправляет запросы на правильный внутренний сервер.
С точки зрения клиента, это всего лишь один постоянный URI, но проблема возникает, когда балансировщик нагрузки переключает экземпляр HAProxy, который обрабатывает запрос. После этого каждый последующий запрос, отправляемый HttpClient, поступает с другого локального порта и обрабатывается внутренним сервером как новое соединение.
Постоянное соединение имеет решающее значение для приложения, так что это в основном нарушает его. Как ни странно, проблема решается сама по себе, как только клиентское приложение перезапускается. Это наводит меня на мысль, что проблема заключается в клиенте, а не в настройке облака или бэкэнд-сервере.
Есть что-то, чего я здесь не хватает? Я подумал, что это может быть проблема с ServicePointManager, создающим ServicePoint, когда соединение проходит через один экземпляр HAProxy, и, поскольку этот объект поддерживается на протяжении всего жизненного цикла приложения, возможно, существует некоторая проблема с его использованием через второй экземпляр HAProxy. При перезапуске приложения экземпляр ServicePoint теряется и создается заново.
Обновление: я заметил, что у объекта ServicePoint сначала есть протокол HTTP 1.1, но как только проблема возникает, она изменилась на 1.0. HTTP 1.1 имеет постоянные соединения по умолчанию, в то время как HTTP 1.0 имеет временные соединения по умолчанию.
Если я изменю протокол объекта ServicePoint на 1.0, когда все будет работать, я получу исключение 502 Bad Gateway (хотя, похоже, оно восстанавливается и возвращается к 1.1 для следующего запроса).
Я предполагаю, что что-то в облачном стеке вызывает изменение протокола на 1.0 после балансировки нагрузки.
1 ответ
Похоже, что-то в облачном стеке устанавливало версию HTTP ответа на 1.0, когда переключатель балансировки нагрузки вызвал первоначальную ошибку. Затем клиентский объект ServicePoint для моей конечной точки был обновлен, так что ServicePoint.HttpBehaviour и ServicePoint.ProtocolVersion были равны 1.0.
HTTP 1.1 имеет постоянные соединения по умолчанию, в то время как 1.0 нет, поэтому соединения не поддерживаются.
Изменение ServicePoint.HttpBehaviour обратно на 1.1 устраняет проблему, хотя я уверен, что на облачном сервере можно сделать правильное исправление конфигурации.
Одна из проблем заключается в том, что HttpBehaviour и ProtocolVersion являются частными свойствами (я менял их с помощью визуальных отладчиков Visual Studio). Они должны быть изменены с помощью отражения, хотя в этом случае я буду зависеть от того, не будет ли оно изменено в будущих версиях.NET