Где я должен начать расследование SocketTimeoutException: время ожидания чтения
Время от времени я вижу следующий файл stacktrace в журнале, в котором время от времени HttpClient
отключается, пытаясь получить доступ к содержимому text/script
с другого сервера. Мой вопрос в том, какие параметры конфигурации следует проверить для моего приложения J2EE, работающего на Weblogic, в Linux? Я специально ищу следующее.
- Параметры тайм-аута JVM
-
HttpClient
params
- Параметр тайм-аута Weblogic или любая другая конфигурация, например количество потоков и т.д.
- Параметры приложения J2EE, такие как конфигурация сервлета и т.д.
- Ресурсы операционной системы, такие как потоки, обработчики файлов и процессор
- Любые другие настройки конфигурации, которые могут влиять на соединение сокета
- Помогла ли вам справиться с потоками?
Здесь мой код
HTTPResponse httpClientResponse;
//do some stuff
httpClientResponse.getStatusCode(); // this is where it fails
и это stacktrace
java.net.SocketTimeoutException: Read timed out
at jrockit.net.SocketNativeIO.readBytesPinned(Native Method)
at jrockit.net.SocketNativeIO.socketRead(SocketNativeIO.java:32)
at java.net.SocketInputStream.socketRead0(SocketInputStream.java)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at HTTPClient.BufferedInputStream.fillBuff(BufferedInputStream.java:206)
at HTTPClient.BufferedInputStream.read(BufferedInputStream.java:126)
at HTTPClient.StreamDemultiplexor.read(StreamDemultiplexor.java:356)
at HTTPClient.RespInputStream.read(RespInputStream.java:147)
at HTTPClient.RespInputStream.read(RespInputStream.java:108)
at HTTPClient.Response.readResponseHeaders(Response.java:1123)
at HTTPClient.Response.getHeaders(Response.java:846)
at HTTPClient.Response.getStatusCode(Response.java:331)
at HTTPClient.RetryModule.responsePhase1Handler(RetryModule.java:92)
at HTTPClient.HTTPResponse.handleResponseImpl(HTTPResponse.java:872)
at HTTPClient.HTTPResponse.access$000(HTTPResponse.java:62)
at HTTPClient.HTTPResponse$2.run(HTTPResponse.java:839)
at HTTPClient.HTTPResponse$2.run(HTTPResponse.java:837)
at
HTTPClient.HttpClientConfiguration.doAction(HttpClientConfiguration.java:666)
at HTTPClient.HTTPResponse.handleResponse(HTTPResponse.java:837)
at HTTPClient.HTTPResponse.getStatusCode(HTTPResponse.java:242)
Спасибо
Я обновляю свой вопрос с помощью FINDINGS ниже.
- На
HttpClient
нет явного тайм-аута, что означает, что http
время сеанса сервера может вступить в силу.
-
SO_TIMEOUT
для HttpClient
равно 0, что означает, что он должен ждать неопределенно долго.
Ответы
Ответ 1
Трек 1
В соответствии с javadocs Httpclient, похоже, не имеет значения по умолчанию для таймаута Socket. Чтобы ответить на вопрос в вашем обновлении, тайм-аут сеанса не будет действовать здесь. По умолчанию Weblogic составляет 30 минут для таймаута сеанса.
Сервер session timeout
представляет количество времени, в течение которого HttpSession
будет сохранено в памяти, если пользователь не обратился к серверу.
Тайм-аут сокета - это время, в течение которого серверный сокет открывается, пока данные передаются обратно вызывающему абоненту. Это может быть даже сервер, который все еще обрабатывает и записывает данные, но он занимает довольно много времени, и клиент только что приурочил его к ожиданию.
Некоторые ссылки показывают, что это значение по умолчанию составляет 60 секунд, но javadocs ничего не говорит, в любом случае вы можете установить это значение примерно на 120 секунд, чтобы увидеть, помогает ли он
http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/params/HttpConnectionParams.html#setSoTimeout(int)
Вам нужно время таймаутов - если это ясно. Значение: появляются ли эти ошибки через 30 секунд, 60 секунд или 5 минут исходящего запроса?
Я бы изменил SO_Timeout и повторил попытку
Трек 2 - параметры ОС
Существуют рекомендуемые параметры BEA для значений NDD, которые определяют, как длинные входящие соединения сохраняются открытыми и сколько стоят в очереди и так далее. В Solaris они запускаются
/usr/sbin/ndd -get /dev/tcp tcp_time_wait_interval
/usr/sbin/ndd -get /dev/tcp tcp_conn_req_max_q
/usr/sbin/ndd -get /dev/tcp tcp_conn_req_max_q0
/usr/sbin/ndd -get /dev/tcp tcp_ip_abort_interval
/usr/sbin/ndd -get /dev/tcp tcp_keepalive_interval
Вы можете проверить документы Oracle для эквивалентных команд в Linux и какие значения они должны быть установлены. В Solaris мой опыт по умолчанию недостаточен, и их необходимо повысить до рекомендаций BEA (Oracle).
Трек 3: Журналы веб-журнала/внешнего доступа
Включены ли на сервере протоколы HTTP Access? Появляются ли эти неудачные запросы с любым размером байта ответа или они показывают 0 размер ответа? Какой код ошибки или код состояния HTTP возвращаются?
Или, возможно, эти тайм-ауты вообще не записываются в журналы доступа?
Здесь я предполагаю, что внешний сервер, на котором происходит аут аут, также является Weblogic, если нет - этот вопрос направлен на команду внешнего сервера для их эквивалентной платформы.
** Другие **
Обычно справки дампов потока, но дампы потоков должны выполняться на сервере, который имеет проблему с таймаутом. Вы являетесь клиентом, и вы успешно получили соединение, после чего оно время при чтении ответа. Так перегружен ли внешний сервер? Отсутствие потоков? CPU высокий? Слишком много одновременных запросов?
Ответ 2
Вы должны исследовать
(a) тайм-аут чтения по умолчанию или явный HttpClient
, в зависимости от того, что используется;
(b) почему сервер не отвечает в течение этого периода, если он должен (просматривать журналы сервера),
(c) иначе почему таймаут слишком короткий. Многие таймауты слишком короткие, например. несколько секунд. Они должны быть приличной частью минуты, и если ожидаемое время отклика больше, удвоить или утроить ожидаемое время отклика.
Ответ 3
Еще один аспект, который не был рассмотрен здесь, - Firewall.
Я обнаружил, что SocketTimeoutExceptions часто могут быть связаны с тем, что порт не открыт для связи или брандмауэр блокирует связь только с выбранными машинами.
Если вы отлаживаете проблему, убедитесь, что вы также изучили, есть ли межсетевой экран между двумя компьютерами, пытающимися связаться, и если есть один, убедитесь, что порты доступны для связи между ними.
Интересные вещи, связанные с проблемами, связанными с брандмауэром, это то, что он не дает вам знать, отключен или не отвечает сервер. Типичное поведение - позволить клиенту ждать навсегда. Поэтому ты всегда остаешься в темноте. Простой telnet на порте сервера должен показать, доступен ли он/открыт для связи.
Надеюсь, это поможет.