繁体   English   中英

击中某些时间后,Servlet停止在Tomcat服务器上工作

[英]Servlet stops working on Tomcat server after some hits or time

我的一些servlet有一个非常奇怪的问题。 下面是我的配置:

  • 文件夹A在Tomcat目录中部署了X个servlet
  • 文件夹B在Tomcat目录中部署了Y个servlet

经过一定时间或到达文件夹B中的任何servlet之后,它会停止正常工作,而与此同时,文件夹A的所有servlet都可以正常工作。

我无法追踪我在哪里做错了。

这两个文件夹的servlet的所有编码都是相同的,唯一的区别是它们正在与不同的DB交互,但这是对DB的非常简单的只读操作。

有任何想法吗?

问题出在记录仪上。 当线程完成执行并且没有明显的方法(例如close())关闭Logger实例时,不会隐式释放Logger实例,因此doGet / doPost线程不会正确退出。

摆脱Logger,或者明确地销毁实例/将其分配为null将解决此问题。

检查此类问题的两件重要事情:

  1. 阅读服务器日志以了解任何异常和堆栈跟踪。 在Tomcat中,它位于/logs文件夹中。 如果发现任何问题,那么这些应该提供足够的信息来自己解决问题。 但是,如果您不了解原因,则需要更新问题以包括相关的异常和堆栈跟踪。 这样,我们可以帮助解释原因,以便解决方案足够明显。

  2. 确保代码不会在任何地方吞下重要的异常。 即,您至少需要在捕获后重新抛出或记录它们。 例如,因此

     try { // ... } catch (SQLException e) { } 

    但更多的是:

     try { // ... } catch (SQLException e) { throw new ServletException(e); } 

    或者, 至少

     try { // ... } catch (SQLException e) { e.printStackTrace(); } 

    这样,它们将被记录到服务器日志中。

在您的特定情况下想到的第一件事是,代码无法在finally块中正确关闭数据库资源,因此DB用完了资源,这导致连接,准备语句和/或执行查询失败。 使用适当的异常处理,应该已经在服务器日志中暗示了这一点。 这是一个基本的启动示例,说明如何以正确的方式编写JDBC代码。 通常的做法是在尽可能短的范围内获取和关闭数据库资源:

public List<Entity> list() throws SQLException {
    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;
    List<Entity> entities = new ArrayList<Data>();

    try {
        connection = database.getConnection();
        statement = connection.createStatement("SELECT id, name, value FROM entity");
        resultSet = statement.executeQuery();
        while (resultSet.next()) {
            Entity entity = new Entity(); 
            entity.setId(resultSet.getLong("id"));
            entity.setName(resultSet.getString("name"));
            entity.setValue(resultSet.getInteger("value"));
            entities.add(entity);
        }
    } finally {
        // Close in reversed order.
        if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {}
        if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
        if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
    }

    return entities;
}

可以忽略close()上的任何异常,但是我更喜欢将它们记录下来,以使您在任何地方都不会丢失任何失败的迹象,即使它很小。

这可能是与数据库超时有关的问题。 也许您的数据库有不同的超时时间? 您是否使用连接池 (您应该!)两个连接的池设置是否相同? 数据库是否配置为具有比您池超时值更大的超时值? 您是否在连接参数中设置了autoReconnect = true?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM