Я использую сервлет на базе Jetty для выполнения RPC, и у меня возникла проблема, когда запрос, который занимает много времени, выдает на сервер следующее исключение:
2012-02-11 21: 07: 07,673 [btpool0-4] DEBUG org.mortbay.log - ИСКЛЮЧЕНИЕ
java.net.SocketTimeoutException: тайм-аут чтения
в java.net.SocketInputStream.socketRead0 (собственный метод)
на java.net.SocketInputStream.read (неизвестный источник)
в org.mortbay.io.ByteArrayBuffer.readFrom (ByteArrayBuffer.java:168)
на org.mortbay.io.bio.StreamEndPoint.fill (StreamEndPoint.java:99)
на org.mortbay.jetty.bio.SocketConnector $ Connection.fill (SocketConnector
.java: 190)
в org.mortbay.jetty.HttpParser.parseNext (HttpParser.java:277)
в org.mortbay.jetty.HttpParser.parseAvailable (HttpParser.java:203)
на org.mortbay.jetty.HttpConnection.handle (HttpConnection.java:357)
в org.mortbay.jetty.bio.SocketConnector $ Connection.run (SocketConnector.
Java: 217)
в org.mortbay.thread.BoundedThreadPool $ PoolThread.run (BoundedThreadPool
.java: 475) 2012-02-11 21: 07: 07,674 [btpool0-4] DEBUG org.mortbay.log
- EOF
Я пытался установить свойство HTTP-запроса Connection, Keep-Alive, но это не имело никакого эффекта, и, насколько я могу судить, http 1.1 (который я почти уверен, что использую) по умолчанию является постоянным.
Так что я думаю, что есть два способа решить эту проблему:
- выяснить, как предотвратить исключение тайм-аута
бросили на всех
Пусть клиент отправит первоначальный запрос без ожидания
для ответа, а затем пинг с отдельными запросами, чтобы проверить, когда
сервер готов.
Обновление (12.02.2012): я установил maxIdleTime, как предложил Тим, и это продлило время до истечения времени ожидания, но затем я начал получать новое исключение:
2012-02-11 23: 24: 01,187 [btpool0-1] DEBUG org.mortbay.log - ИСКЛЮЧЕНИЕ
java.io.IOException: существующее соединение было принудительно закрыто
удаленный хост в sun.nio.ch.SocketDispatcher.read0 (собственный метод) в
sun.nio.ch.SocketDispatcher.read (неизвестный источник) в
sun.nio.ch.IOUtil.readIntoNativeBuffer (неизвестный источник) в
sun.nio.ch.IOUtil.read (неизвестный источник) в
sun.nio.ch.SocketChannelImpl.read (неизвестный источник) в
org.mortbay.io.nio.ChannelEndPoint.fill (ChannelEndPoint.java:129) в
org.mortbay.jetty.HttpParser.parseNext (HttpParser.java:277) в
org.mortbay.jetty.HttpParser.parseAvailable (HttpParser.java:203) в
org.mortbay.jetty.HttpConnection.handle (HttpConnection.java:357) в
org.mortbay.io.nio.SelectChannelEndPoint.run (SelectChannelEndPoint.java:329)
в
org.mortbay.thread.BoundedThreadPool $ PoolThread.run (BoundedThreadPool.java:475)
Так что что-то вне Jetty убивало соединение, я подозреваю, скорее всего, брандмауэр. В итоге я заставил сервер обрабатывать запрос несколькими потоками; исходный поток немедленно отвечал на запрос http, а второй поток запускался для выполнения действия, которое занимало много времени. Затем клиент будет запрашивать http-запросы, чтобы проверить, завершено ли действие на сервере.