长时间轮询后10秒后,Tomcat 7服务器错误 [英] Tomcat 7 server error after 10 seconds when long polling
问题描述
我正在尝试在Java Web应用程序中实现长轮询.该应用程序是使用Spring MVC 3.2编写的,并且我使用DeferredResult对象(它表示Servlet 3.0异步响应功能).
I'm trying to achieve long-polling in Java web application. The application is written using Spring MVC 3.2 and I make use of DeferredResult object (it represents Servlet 3.0 async response capability).
问题是,使用DeferredResult时,每次发送请求10秒钟后,我都会收到内部服务器错误(代码500).预期结果是30秒后的文本数据.我的应用程序日志中没有任何内容,Tomcat日志中没有任何内容,但是在FireFox网络监视器中却没有,我看到了这个500错误.
The problem is that when using DeferredResult I get internal server error (code 500) after 10 seconds every time I send request. Expected result is text data after 30 seconds. There is nothing in my app logs, nothing in Tomcat logs but in FireFox network monitor I see this 500 error.
另一方面,当我发送同步请求并在服务器中保留30秒钟时,它成功完成.
On the other hand when I send sync request and just hold it for 30 seconds in server it completes successfully.
有人可以帮我吗?
本文结尾处有一个测试应用程序下载链接.这是一个Maven应用程序.
There is a test application download link at the end of this post. It is a maven application.
这是我的应用代码:
ResponseController.java
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
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-dispatcher-servlet.xml
mvc-dispatcher-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请求进行异步响应
JQuery request for async response
$.ajax({
url : "responses/async",
type : "GET",
timeout : 60000,
dataType : "json",
success : function(){
alert('SUCCESS');
},
error : function(){
alert('FAILURE');
}
});
jQuery请求同步响应
JQuery request for sync response
$.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文件
Tomcat server.xml file
<?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 "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
我的环境配置
-
OS:Linux Mint 16
OS: Linux Mint 16
服务器:Apache Tomcat 7.0.55
Server: Apache Tomcat 7.0.55
Java:Java 1.7.0_67
Java: Java 1.7.0_67
更新1
以下是响应数据:
响应标题:
连接:关闭"
内容长度:"0"
日期:"2014年10月27日星期一19:48:10 GMT"
Date : "Mon, 27 Oct 2014 19:48:10 GMT"
服务器:"Apache-Coyote/1.1"
Server : "Apache-Coyote/1.1"
更新2
这是我的应用程序日志.我已将日志记录级别配置为ALL.不幸的是,它们根本没有错误. (我对tomcat日志执行了相同的操作,但结果相同):
Here are my application logs. I've configured logging level to ALL. Unfortunatelly there is no error in them at all. (I did the same with tomcat logs with the same result):
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.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter@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 [org.springframework.web.context.request.async.DeferredResult@4810881c]
2014-11-01 15:33:09 TRACE HandlerMethodReturnValueHandlerComposite:78 - Testing if return value handler [org.springframework.web.servlet.mvc.method.annotation.ModelAndViewMethodReturnValueHandler@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 [org.springframework.web.method.annotation.ModelMethodProcessor@6c362b54] 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.servlet.mvc.method.annotation.ViewMethodReturnValueHandler@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.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor@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.servlet.mvc.method.annotation.CallableMethodReturnValueHandler@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.servlet.mvc.method.annotation.DeferredResultMethodReturnValueHandler@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: org.apache.catalina.connector.RequestFacade@655d2842
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]
推荐答案
好.我找到了解决方法.
Ok. I've found a solution.
在Tomcat配置(在server.xml文件中)中,有一个HTTP/1.1连接器.我要强调的是,connectionTimeout参数定义了每个连接的超时,但是没有定义.
In Tomcat configuration (in server.xml file) there is a HTTP/1.1 connector. I tought that connectionTimeout parameter defines timeout for every connections but it does not.
对于异步连接(例如我的情况),有一个单独的参数称为 asyncTimeout
.默认值为10秒.
For asynchronous connections (like in my case) there is separate parameter called asyncTimeout
. It's default value is 10 seconds.
像这样设置:
<Connector port="8080" protocol="HTTP/1.1" asyncTimeout="60000" connectionTimeout="20000" redirectPort="8443" />
解决了我的问题.
这篇关于长时间轮询后10秒后,Tomcat 7服务器错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!