2

Я пытаюсь добиться длительного опроса в веб-приложении Java. Приложение написано с использованием Spring MVC 3.2, и я использую объект DeferredResult (он представляет собой возможность ответа на ассемблер Servlet 3.0).Ошибка сервера Tomcat 7 через 10 секунд при длительном опросе

Проблема заключается в том, что при использовании DeferredResult я получаю внутреннюю ошибку сервера (код 500) через 10 секунд каждый раз, когда я отправляю запрос. Ожидаемый результат - текстовые данные через 30 секунд. В моих журналах приложений ничего нет, ничего в журналах Tomcat, но в сетевом мониторе FireFox я вижу эту ошибку 500.

С другой стороны, когда я отправляю запрос на синхронизацию и просто удерживаю ее в течение 30 секунд на сервере, она завершается успешно.

Может ли кто-нибудь помочь мне с этим?

В конце этого сообщения есть ссылка для загрузки тестового приложения. Это приложение maven.

Вот мое приложение код:

ResponseController.java

@Controller 
@RequestMapping("responses") 
public class ResponseController { 

    @Autowired 
    private ResponseService messagesService; 

    @RequestMapping(value="/async", method=RequestMethod.GET) 
    @ResponseBody 
    public DeferredResult<String> getAsyncUpdate() { 
     return messagesService.getAsyncUpdate(); 
    } 

    @RequestMapping(value="/sync", method=RequestMethod.GET) 
    @ResponseBody 
    public String getSyncUpdate() { 
     return messagesService.getSyncUpdate(); 
    } 

} 

ResponseService.java

@Service 
public class ResponseService { 

    private DeferredResult<String> deferredResult; 

    public DeferredResult<String> getAsyncUpdate(){ 
     deferredResult = new DeferredResult<String>(); 
     return deferredResult; 
    } 

    public String getSyncUpdate(){ 
     long startTime = System.currentTimeMillis(); 
     while(System.currentTimeMillis() - startTime <30000){ 

     } 
     return "RESULT"; 
    } 

    @Scheduled(fixedDelay=500) 
    public void refresh(){ 
     if(deferredResult != null){ 
      long startTime = System.currentTimeMillis(); 
      while(System.currentTimeMillis() - startTime <30000){ 

      } 
      deferredResult.setResult("RESULT"); 
     } 
    } 

} 

MVC-диспетчерская-servlet.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:jee="http://www.springframework.org/schema/jee" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:task="http://www.springframework.org/schema/task" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation=" 
     http://www.springframework.org/schema/beans  
     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
     http://www.springframework.org/schema/mvc  
     http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd 
     http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/context/spring-context-3.2.xsd 
     http://www.springframework.org/schema/tx 
     http://www.springframework.org/schema/tx/spring-tx.xsd 
     http://www.springframework.org/schema/aop 
     http://www.springframework.org/schema/aop/spring-aop.xsd 
     http://www.springframework.org/schema/jee 
     http://www.springframework.org/schema/jee/spring-jee-3.2.xsd 
     http://www.springframework.org/schema/task 
     http://www.springframework.org/schema/task/spring-task-3.0.xsd"> 

    <context:component-scan base-package="pl.prv.mra.test.app" /> 
    <context:annotation-config/> 

    <aop:aspectj-autoproxy/> 

    <mvc:annotation-driven > 
     <mvc:message-converters> 
      <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" /> 
     </mvc:message-converters> 
    </mvc:annotation-driven> 

    <task:annotation-driven/> 

    <mvc:resources location="/resources/**" mapping="/resources/**"/> 

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <property name="prefix" value="/WEB-INF/pages/"/> 
     <property name="suffix" value=".jsp"/> 
    </bean> 

</beans> 

запрос JQuery для асинхронного esponse

$.ajax({ 
    url : "responses/async", 
    type : "GET", 
    timeout : 60000, 
    dataType : "json", 
    success : function(){ 
     alert('SUCCESS'); 
    }, 
    error : function(){ 
     alert('FAILURE'); 
    } 
}); 

JQuery запрос для ответа синхронизации

$.ajax({ 
    url : "responses/sync", 
    type : "GET", 
    timeout : 60000, 
    dataType : "json", 
    success : function(){ 
     alert('SUCCESS'); 
    }, 
    error : function(){ 
     alert('FAILURE'); 
    } 
}); 

web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
    version="3.0"> 

    <display-name>test-app</display-name> 

    <servlet> 
     <servlet-name>mvc-dispatcher</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <async-supported>true</async-supported> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>mvc-dispatcher</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value> 
    </context-param> 

    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 

</web-app> 

Tomcat server.xml файл

<?xml version='1.0' encoding='utf-8'?> 
<Server port="8005" shutdown="SHUTDOWN"> 
    <Listener className="org.apache.catalina.core.AprLifecycleListener" 
     SSLEngine="on" /> 
    <Listener className="org.apache.catalina.core.JasperListener" /> 
    <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /> 
    <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> 
    <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> 

    <GlobalNamingResources> 
     <Resource name="UserDatabase" auth="Container" 
      type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" 
      factory="org.apache.catalina.users.MemoryUserDatabaseFactory" 
      pathname="conf/tomcat-users.xml" /> 
    </GlobalNamingResources> 

    <Service name="Catalina"> 

     <Connector port="8080" protocol="HTTP/1.1" 
      connectionTimeout="20000" redirectPort="8443" /> 

     <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> 

     <Engine name="Catalina" defaultHost="localhost"> 

      <Realm className="org.apache.catalina.realm.LockOutRealm"> 
       <Realm className="org.apache.catalina.realm.UserDatabaseRealm" 
        resourceName="UserDatabase" /> 
      </Realm> 

      <Host name="localhost" appBase="webapps" unpackWARs="true" 
       autoDeploy="true"> 

       <Valve className="org.apache.catalina.valves.AccessLogValve" 
        directory="logs" prefix="localhost_access_log." suffix=".txt" 
        pattern="%h %l %u %t &quot;%r&quot; %s %b" /> 

      </Host> 
     </Engine> 
    </Service> 
</Server> 

Моя конфигурация среды

  • ОС: Linux Mint 16

  • Сервер: Apache Tomcat 7.0.55

  • Java: Java 1.7.0_67

Test application download link

ОБНОВЛЕНИЕ 1


Вот данные ответа:

заголовки отклика:

Connecti на: "близко"

Content-Length: "0"

Дата: "пн, 27 октября 2014 19:48:10 GMT"

Сервер: "Apache-Coyote/1,1"

UPDATE 2


Вот мои журналы приложений. Я настроил уровень ведения журнала для ВСЕ. К сожалению, в них нет ошибки. (Я сделал то же самое с журналами tomcat с тем же результатом):

2014-11-01 15:33:09 DEBUG RequestMappingHandlerMapping:220 - Looking up handler method for path /responses/async 
2014-11-01 15:33:09 TRACE RequestMappingHandlerMapping:264 - Found 1 matching mapping(s) for [/responses/async] : [{[/responses/async],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}] 
2014-11-01 15:33:09 DEBUG RequestMappingHandlerMapping:227 - Returning handler method [public org.springframework.web.context.request.async.DeferredResult<java.lang.String> pl.prv.mra.test.app.controllers.ResponseController.getAsyncUpdate()] 
2014-11-01 15:33:09 DEBUG DefaultListableBeanFactory:246 - Returning cached instance of singleton bean 'responseController' 
2014-11-01 15:33:09 TRACE DispatcherServlet:1122 - Testing handler adapter [org.springframework[email protected]7e036b3] 
2014-11-01 15:33:09 DEBUG DispatcherServlet:912 - Last-Modified value for [/test-app/responses/async] is: -1 
2014-11-01 15:33:09 TRACE HandlerMethod:129 - Invoking [getAsyncUpdate] method with arguments [] 
2014-11-01 15:33:09 TRACE HandlerMethod:135 - Method [getAsyncUpdate] returned [[email protected]0881c] 
2014-11-01 15:33:09 TRACE HandlerMethodReturnValueHandlerComposite:78 - Testing if return value handler [org.springframework.web.ser[email protected]2a426218] supports [org.springframework.web.context.request.async.DeferredResult<java.lang.String>] 
2014-11-01 15:33:09 TRACE HandlerMethodReturnValueHandlerComposite:78 - Testing if return value handler [[email protected]c362b54] supports [org.springframework.web.context.request.async.DeferredResult<java.lang.String>] 
2014-11-01 15:33:09 TRACE HandlerMethodReturnValueHandlerComposite:78 - Testing if return value handler [org.springframework[email protected]5856cf4c] supports [org.springframework.web.context.request.async.DeferredResult<java.lang.String>] 
2014-11-01 15:33:09 TRACE HandlerMethodReturnValueHandlerComposite:78 - Testing if return value handler [org.springframew[email protected]2b43b3e3] supports [org.springframework.web.context.request.async.DeferredResult<java.lang.String>] 
2014-11-01 15:33:09 TRACE HandlerMethodReturnValueHandlerComposite:78 - Testing if return value handler [org.springframework.web[email protected]deae877] supports [org.springframework.web.context.request.async.DeferredResult<java.lang.String>] 
2014-11-01 15:33:09 TRACE HandlerMethodReturnValueHandlerComposite:78 - Testing if return value handler [org.springframework.web.servl[email protected]3943e3c4] supports [org.springframework.web.context.request.async.DeferredResult<java.lang.String>] 
2014-11-01 15:33:10 DEBUG WebAsyncManager:429 - Concurrent handling starting for GET [/test-app/responses/async] 
2014-11-01 15:33:10 TRACE DispatcherServlet:1028 - Cleared thread-bound request context: [email protected] 
2014-11-01 15:33:10 DEBUG DispatcherServlet:963 - Leaving response open for concurrent processing 
2014-11-01 15:33:10 TRACE XmlWebApplicationContext:332 - Publishing event in WebApplicationContext for namespace 'mvc-dispatcher-servlet': ServletRequestHandledEvent: url=[/test-app/responses/async]; client=[127.0.0.1]; method=[GET]; servlet=[mvc-dispatcher]; session=[55143812B6586F66C0001D3F41B1947C]; user=[null]; time=[13ms]; status=[OK] 
2014-11-01 15:33:10 TRACE XmlWebApplicationContext:332 - Publishing event in Root WebApplicationContext: ServletRequestHandledEvent: url=[/test-app/responses/async]; client=[127.0.0.1]; method=[GET]; servlet=[mvc-dispatcher]; session=[55143812B6586F66C0001D3F41B1947C]; user=[null]; time=[13ms]; status=[OK] 
+0

В разделе Ответ на вкладке сети должно быть указано описание ошибки. Покажите это здесь. – Bnrdo

+0

Я обновил сообщение с заголовками ответов. –

+0

Пожалуйста, обновите его с помощью тела ответа. – Bnrdo

ответ

5

Ok. Я нашел решение.

В конфигурации Tomcat (в файле server.xml) имеется соединитель HTTP/1.1. Я утверждал, что параметр connectionTimeout определяет тайм-аут для всех подключений, но это не так.

Для асинхронных соединений (как в моем случае) имеется отдельный параметр, называемый asyncTimeout. Значение по умолчанию - 10 секунд.

Установка так:

<Connector port="8080" protocol="HTTP/1.1" asyncTimeout="60000" connectionTimeout="20000" redirectPort="8443" /> 

решить мою проблему.

Смежные вопросы