У меня есть веб-приложение и клиент, оба написаны на Java. Для чего это стоит, клиент и сервер оба на Windows. Клиент выдает HTTP GET через Apache HttpClient . Сервер блокируется на срок до минуты, и если в течение этой минуты клиенту не поступило сообщений, сервер возвращает HTTP 204 Нет содержимого. В противном случае, как только сообщение готово для клиента, оно возвращается с телом HTTP 200 OK.
Вот что меня озадачило: Периодически для определенного подмножества клиентов - всегда клиентов с явно нестабильными сетевыми подключениями - клиент выдает GET, сервер получает и обрабатывает GET, но клиент сидит навсегда. Включив журналы отладки для клиента, я вижу, что HttpClient все еще ожидает самую первую строку ответа.
На сервере не генерируется исключение, по крайней мере, нигде ничего не зарегистрировано, ни Tomcat, ни моим веб-приложением. Согласно журналам отладки, есть все признаки того, что сервер успешно ответил клиенту. Тем не менее, клиент не показывает никаких признаков получения чего-либо. Клиент зависает на неопределенный срок в HttpClient.executeMethod . Это становится очевидным после истечения времени сеанса, и клиент предпринимает действие, которое заставляет другой поток выдать HTTP-запрос POST. Конечно, POST терпит неудачу, потому что сеанс истек. В некоторых случаях часы истекли между истечением сеанса и клиентом, выполняющим POST и обнаружившим этот факт. Все это время executeMethod
все еще ожидает строку ответа HTTP.
Когда я использую WireShark, чтобы увидеть, что действительно происходит на уровне проводов, этот сбой не происходит. То есть этот сбой произойдет в течение нескольких часов для определенных клиентов, но когда WireShark работает на обоих концах, эти же клиенты будут работать в течение ночи, 14 часов, без сбоев.
Кто-нибудь еще сталкивался с чем-то подобным? Что в мире может вызвать это? Я думал, что TCP / IP гарантирует доставку пакетов даже через кратковременные глюки сети. Если я установлю SO_TIMEOUT и сразу же повторю запрос по истечении времени ожидания, повтор всегда будет успешным. (Конечно, я сначала отменяю запрос тайм-аута и освобождаю соединение, чтобы убедиться, что будет использоваться новый сокет.)
Мысли? Идеи? Есть ли какие-либо настройки TCP / IP, доступные для Java, или настройки реестра в Windows, которые позволят более агрессивные попытки TCP / IP для потерянных пакетов?