java.net.SocketTimeoutException: тайм-аут чтения под tomcat

У меня есть веб-приложение на основе Tomcat. Я периодически получаю следующее исключение,

Caused by: java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:150)
    at java.net.SocketInputStream.read(SocketInputStream.java:121)
    at org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:532)
    at org.apache.coyote.http11.InternalInputBuffer.fill(InternalInputBuffer.java:501)
    at org.apache.coyote.http11.InternalInputBuffer$InputStreamInputBuffer.doRead(InternalInputBuffer.java:563)
    at org.apache.coyote.http11.filters.IdentityInputFilter.doRead(IdentityInputFilter.java:124)
    at org.apache.coyote.http11.AbstractInputBuffer.doRead(AbstractInputBuffer.java:346)
    at org.apache.coyote.Request.doRead(Request.java:422)
    at org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:290)
    at org.apache.tomcat.util.buf.ByteChunk.substract(ByteChunk.java:431)
    at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:315)
    at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:200)
    at java.nio.channels.Channels$ReadableByteChannelImpl.read(Channels.java:385)

К сожалению, у меня нет доступа к клиенту, поэтому я просто пытаюсь подтвердить по разным причинам, что это может произойти,

  1. Сервер пытается прочитать данные из запроса, но это занимает больше времени, чем значение тайм-аута для получения данных от клиента. Тайм-аут здесь, как правило, будет соединителем tomcat -> атрибут connectionTimeout.

  2. У клиента установлен тайм-аут чтения, и серверу требуется больше времени, чтобы ответить.

  3. Один из потоков, через который я прошел, сказал, что это может произойти с высоким параллелизмом, и если включен keepalive.

Для #1 начальное значение, которое я установил, было 20 секунд, я увеличил его до 60 секунд, проверим и посмотрим, есть ли какие-либо изменения.

Между тем, если кто-то из вас, ребята, может дать вам экспертное мнение по этому вопросу, это будет очень полезно. Или по любой другой причине, вы можете подумать о том, что может вызвать эту проблему.

Заранее спасибо.

Vicky

8 ответов

Сервер пытается прочитать данные из запроса, но это занимает больше времени, чем значение тайм-аута для получения данных от клиента. Тайм-аут здесь, как правило, будет соединителем tomcat -> атрибут connectionTimeout.

Правильный.

У клиента установлен тайм-аут чтения, и серверу требуется больше времени, чтобы ответить.

Нет, это приведет к тайм-ауту у клиента.

Один из потоков, через который я прошел, сказал, что это может произойти с высоким параллелизмом, и если включен keepalive.

Это явно догадки и совершенно неверные. Это происходит тогда и только тогда, когда данные не поступают в течение тайм-аута. Период. Загрузка, поддержка активности и параллелизм не имеют к этому никакого отношения.

Это просто означает, что клиент не отправляет. Вам не нужно беспокоиться об этом. Клиенты браузера приходят и уходят всевозможными странными способами.

Для тех, кто сталкивается с этим и хочет быстрого решения "переход в погоню", вот оно:

  1. Найдите файл "server.xml" в папке "conf" под базовым каталогом Tomcat (т.е. %CATALINA_HOME%/conf/server.xml).
  2. Откройте файл в редакторе и найдите <Connector,
  3. Найдите соответствующий соединитель, для которого истекло время ожидания - это обычно будет соединитель HTTP, т.е. protocol="HTTP/1.1",
  4. Если connectionTimeout значение устанавливается на разъеме, его может потребоваться увеличить - например, с 20000 миллисекунд (= 20 секунд) до 120000 миллисекунд (= 2 минуты). Если нет connectionTimeout Значение свойства устанавливается на соединителе, по умолчанию оно составляет 60 секунд - если этого недостаточно, возможно, потребуется добавить свойство.
  5. Перезапустите Tomcat
Connection.Response resp = Jsoup.connect(url) //
                .timeout(20000) //
                .method(Connection.Method.GET) //
                .execute();

На самом деле, ошибка возникает, когда у вас медленный интернет, поэтому постарайтесь максимально увеличить время ожидания, и тогда ваш код будет работать точно так же, как и у меня.

У меня была такая же проблема при попытке прочитать данные из тела запроса. В моем случае это происходит случайным образом только на мобильных клиентских устройствах. Так что я увеличил connectionUploadTimeoutдо 1 мин, как предлагается по этой ссылке

У меня такая же проблема. Ошибка java.net.SocketTimeoutException: ошибка истечения времени ожидания чтения возникает на Tomcat под Mac 11.1, но отлично работает в Mac 10.13. Та же папка Tomcat, тот же файл WAR. Пытался установить значения тайм-аута выше, но ничего из того, что я делаю, не работает. Если я запускаю тот же код SpringBoot в обычном приложении Java (за пределами Tomcat 9.0.41 (пробовал и другие версии), то он тоже работает.

Mac 11.1, похоже, мешает Tomcat.

В качестве еще одного теста, если я скопирую файл WAR в экземпляр AWS EC2, он и там будет работать нормально.

Несколько дней потратил на то, чтобы понять это, но не смог решить.

Предложения очень приветствуются! :)

Это произошло с моим приложением, на самом деле я использовал один объект, который вызывался несколькими функциями, и они не были потокобезопасными.

Что-то вроде этого :

      Class A{
    Object B;
    function1(){
        B.doSomething();
    }
    function2(){
        B.doSomething();
    }
}

Поскольку они не были потокобезопасными, я получал следующие ошибки:

redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: сокет закрыт

и

redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: время ожидания чтения истекло

Вот как я это исправил:

      Class A{
    function1(){
        Object B;
        B.doSomething();
    }
    function2(){    
        Object B;
        B.doSomething();
    }
}

Надеюсь, поможет

Это означает, что время ожидания ответа вашего сервера истекло. Это вызвано конфигурацией сервера и интернет-ответом.

Я использую 11.2 и получил таймауты.

Я решил использовать версию jsoup ниже.

    <dependency>
        <groupId>org.jsoup</groupId>
        <artifactId>jsoup</artifactId>
        <version>1.7.2</version>
        <scope>compile</scope>
    </dependency>
Другие вопросы по тегам