age*_*ntx 15 java spring tomcat spring-mvc amazon-dynamodb
我有一个Web应用程序(使用Spring 3.1),它使用@Scheduled Annotation定期执行一个worker任务(计划延迟).工作人员任务打开与AWS DynamoDb的连接,并执行一些数据库读取/更新.当我停止webapp(来自Tomcat经理)时,我在catalina.out中收到此消息:
"严重:Web应用程序[]似乎已经启动了一个名为[java-sdk-http-connection-reaper]但未能阻止它的线程.这很可能会造成内存泄漏."
我感觉这与我的计划任务有关,即使在Tomcat停止之后仍在运行.
@Service
public class TaskScheduler implements ApplicationListener<ContextClosedEvent>{
@Autowired
private WorkerTask workerTask;
AmazonDynamoDBClient myDbConn = null;
private TaskScheduler() {
myDbConn = new AWSConnector("aws.properties").getDynamoConnection();
}
/*
* Will be repeatedly called, 10 seconds after the finish of the previous
* invocation.
*/
@Scheduled(fixedDelay=100000)
public void process() {
System.out.println("Scheduling worker task");
//worker task does some db read/writes
Future<String> status = workerTask.work(myDbConn);
if (status.isDone()) {
System.out.println("Completed Task");
return;
}
}
@Override
public void onApplicationEvent(ContextClosedEvent arg0) {
if(event instanceof ContextClosedEvent) {
// TODO Auto-generated method stub
if(myDbConn != null) {
this.myDbConn.shutdown();
}
}
}
Run Code Online (Sandbox Code Playgroud)
调度员servlet.xml中:
<task:annotation-driven scheduler="taskScheduler"/>
<task:scheduler id="taskScheduler" pool-size="2"/>
......
<bean id="TaskScheduler" class="com.sample.TaskScheduler"/>
Run Code Online (Sandbox Code Playgroud)
我这样做了吗?a)我没有明确启动TaskScheduler.所以我假设spring负责启动这项服务.调用'this.myDbConn.shutdown()'.尽管如此,我还是得到了错误.我正在使用Spring MVC.
Dav*_*ell 13
这可能是由AWS库在后台启动一个名为com.amazonaws.http.IdleConnectionReaper的线程引起的.
您可以通过实现ServletContextListener来关闭它,以便在关闭时关闭它
public class YourListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent contextEvent) {
}
@Override
public void contextDestroyed(ServletContextEvent contextEvent) {
try {
com.amazonaws.http.IdleConnectionReaper.shutdown();
} catch (Throwable t) {
// log the error
}
}
}
Run Code Online (Sandbox Code Playgroud)
并将其添加到您的web.xml
<listener>
<listener-class>
your.package.YourListener
</listener-class>
</listener>
Run Code Online (Sandbox Code Playgroud)
我也遇到过这个问题,但我决定采用上述@ David_Wartell的替代解决方案.
我跟踪了从Amazon的aws-java-sdk库中创建一个有问题的对象/对象的类,这些库启动了IdleConnectionReaper线程但从未关闭(这些是com.amazonaws.services.ec2.AmazonEC2Client和com.amazonaws.services .cloudwatch.AmazonCloudWatchClient).然后我在这个类中添加了一个destroy()方法,它调用静态方法com.amazonaws.http.IdleConnectionReaper.shutdown().当类被垃圾收集并且使用Spring applicationContext.xml配置时,将调用destroy方法.这样做的好处是它甚至可以用于非Web应用程序,并且可以从您的Web上下文中解除线程关闭.正确的解决方案是启动IdleConnectionReaper线程的amazon aws-java-sdk库中的类应该关闭它但它们不会 - 因此这个错误.有关我的解决方案,请参阅下面的参考和代码段:
applicationContext.xml中
<bean id="YourBeanName" class="com.your.package.name.YourBeanName" destroy-method="destroy">
<!-- other optional configuration goes here -->
</bean>
Run Code Online (Sandbox Code Playgroud)
YourBeanName.java - (创建有问题的亚马逊对象的类)
public class YourBeanName {
// omitted code
public void destroy() {
com.amazonaws.http.IdleConnectionReaper.shutdown();
}
// omitted code
}
Run Code Online (Sandbox Code Playgroud)
引用:
亚马逊论坛 - 关闭IdleConnectionReaper
Spring文档 - 自定义bean的性质
归档时间: |
|
查看次数: |
6852 次 |
最近记录: |