Tomcat Web应用程序自动停止

时间:2013-04-15 08:36:38

标签: java tomcat web-applications

我有一台运行CentOS 5.9的专用服务器,Apache-Tomcat 5.5.36。我编写了一个JAVA Web应用程序,每分钟运行一次,从多个传感器收集数据。我使用ScheduledExecutorService来执行线程。 (每分钟一个线程用于每个传感器,并且可以有超过一百个传感器)线程的流程是

  1. 从数据库中收集传感器信息。
  2. 将命令发送到仪器以收集数据。
  3. 使用数据值更新数据库。
  4. 还有另一个应用程序每分钟检查一次数据库并将警报发送给用户(如有必要)。我使用jvisualVM监视应用程序,我找不到任何内存泄漏。为每个线程。应用程序工作正常但经过一段时间(24小时 - 48小时)后,应用程序停止工作。我无法找出问题所在,是服务器配置问题,线程太多还是什么?

    有没有人知道可能出现什么问题,或者有没有人做过那种想法?请帮忙,谢谢

    更新:包括代码

    public class Scheduler {
           private final ScheduledExecutorService scheduler = 
              Executors.newScheduledThreadPool(1);
           public void startProcess(int start) {
               final Runnable uploader = new Runnable() {
                @SuppressWarnings("rawtypes")
                public void run() 
                { 
                    //Select data from the database
                    ArrayList dataList = getData();
                    for(int i=0;i<dataList.size();i++)
                    {
                        String args = dataList.get(i).toString();
                        ExecutorThread comThread = new ExecutorThread(args...);
                        comThread.start();
                    }
                }
            };
            scheduler.scheduleAtFixedRate(uploader, 0, 60 , TimeUnit.SECONDS);
           }
        }
    
    public class ExecutorThread extends Thread {
    
        private variables...
        public CommunicationThread(args..)
        {
            //Initialise private variable
        }
    
        public void run()
        {
            //Collect data from sensor
            //Update Database
        }
    }
    

2 个答案:

答案 0 :(得分:1)

没有代码就不能说太多,但是你需要确保你的线程总是正常退出 - 不会在内存中挂起任何异常,关闭与数据库的连接等。

此外,为了监视您的应用程序,您可以每隔一段时间进行一次线程转储,以查看应用程序生成的线程数。

另一个建议是configure Tomcat to take a heap dump on OutOfMemoryError。如果这是一个问题,你将能够分析填补内存的内容

答案 1 :(得分:1)

请注意ScheduledExecutorService.schedule... Javadoc

中的这条无关紧要的行

如果任务的任何执行遇到异常,则后续执行将被禁止。

这意味着,如果您在某个时间点遇到Exception但未处理它,则Exception会传播到ScheduledExecutorService,这会导致您的任务无效。

要避免此问题,您需要确保整个 Runnable包含在try...catch中且Exception保证永远不会被处理。

您还可以扩展ScheduledExecutorService(也在javadoc中提及)来处理未捕获的例外: -

final ScheduledExecutorService ses = new ScheduledThreadPoolExecutor(10){

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        if (t == null && r instanceof Future<?>) {
            try {
                Object result = ((Future<?>) r).get();
            } catch (CancellationException ce) {
                t = ce;
            } catch (ExecutionException ee) {
                t = ee.getCause();
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt(); // ignore/reset
            }
        }
        if (t != null) {
            System.out.println(t);
        }
    }
};

此处afterExecute方法仅System.out.println Throwable,但它可以执行其他操作。提醒用户,重启任务等......