【问题标题】:Tomcat web application stops automaticallyTomcat Web 应用程序自动停止
【发布时间】:2013-04-15 08:36:38
【问题描述】:

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

  1. 从数据库中收集传感器信息。
  2. 向仪器发送命令以收集数据。
  3. 使用数据值更新数据库。

还有另一个应用程序每分钟检查一次数据库并向用户发送警报(如有必要)。我已经使用 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
    }
}

【问题讨论】:

  • 应用程序正在运行,您无法从数据库中获取数据是这个问题吗?
  • 请注意ScheduledExecutorService.schedule... javadoc 中的这句无害的行 - “如果任务的任何执行遇到异常,则后续执行将被抑制”。
  • 我没有看到任何异常处理 - 我认为我的回答会解决问题。

标签: java tomcat web-applications


【解决方案1】:

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

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

另一个建议是configure Tomcat to take a heap dump on OutOfMemoryError。如果这是一个问题,您将能够分析是什么填满了内存

【讨论】:

    【解决方案2】:

    注意ScheduledExecutorService.schedule... Javadoc 的这条无害线路

    如果任务的任何执行遇到异常,后续的执行将被抑制。

    这意味着,如果您在某个时刻遇到Exception 而没有处理它,Exception 将传播到ScheduledExecutorService 中,它会终止您的任务。

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

    您还可以扩展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.printlns Throwable 但它可以做其他事情。提醒用户、重启任务等...

    【讨论】:

    • 感谢您的提示...我想我正在处理所有异常但我会尝试您的解决方案..
    最近更新 更多