简体   繁体   English

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

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

I have a very strange issue with some of my servlets. 我的一些servlet有一个非常奇怪的问题。 Below is my configuration: 下面是我的配置:

  • Folder A has X number of servlets deployed in Tomcat directory 文件夹A在Tomcat目录中部署了X个servlet
  • Folder B has Y number of servlets deployed in Tomcat directory 文件夹B在Tomcat目录中部署了Y个servlet

After certain amount of time or hits to any of the servlets in Folder B, it stops working properly, whereas at same time all servlets of Folder A works fine. 经过一定时间或到达文件夹B中的任何servlet之后,它会停止正常工作,而与此同时,文件夹A的所有servlet都可以正常工作。

I am not able to trace where I am doing mistake. 我无法追踪我在哪里做错了。

All coding for both folder's servlets is the same, the only difference is they are interacting with different DB's, but it is very simple read only operation with DB though. 这两个文件夹的servlet的所有编码都是相同的,唯一的区别是它们正在与不同的DB交互,但这是对DB的非常简单的只读操作。

Any ideas? 有任何想法吗?

The issue lies with the Logger. 问题出在记录仪上。 The Logger instance is not implicitly released when the thread finishes execution and since there is no obvious method such as close() to close the Logger instance, the doGet / doPost thread does not exit properly. 当线程完成执行并且没有明显的方法(例如close())关闭Logger实例时,不会隐式释放Logger实例,因此doGet / doPost线程不会正确退出。

Getting rid of the Logger, or alternatively, explicitly destroying the instance / assigning it to null will solve the problem. 摆脱Logger,或者明确地销毁实例/将其分配为null将解决此问题。

Two important things to check in this kind of problems: 检查此类问题的两件重要事情:

  1. Read the server logs for any exceptions and stacktraces. 阅读服务器日志以了解任何异常和堆栈跟踪。 In Tomcat it's located in /logs folder. 在Tomcat中,它位于/logs文件夹中。 If you found any, then those should provide sufficient information to fix the problem yourself. 如果发现任何问题,那么这些应该提供足够的信息来自己解决问题。 But if you don't understand the cause, then you need to update your question to include the relevant exceptions and stacktraces. 但是,如果您不了解原因,则需要更新问题以包括相关的异常和堆栈跟踪。 This way we can assist in explaining the cause so that the solution is obvious enough. 这样,我们可以帮助解释原因,以便解决方案足够明显。

  2. Ensure that the code is not swallowing important exceptions anywhere. 确保代码不会在任何地方吞下重要的异常。 Ie you need to at least rethrow or log them after catching. 即,您至少需要在捕获后重新抛出或记录它们。 Eg thus not : 例如,因此

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

    But more so: 但更多的是:

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

    Or, at least : 或者, 至少

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

    This way they will be logged to the server logs. 这样,它们将被记录到服务器日志中。

One of first things which comes to mind in your particular case is that the code is not closing database resources properly in finally block and the DB thus runs out of resources which leads to a failure in connecting, preparing statement and/or executing the query. 在您的特定情况下想到的第一件事是,代码无法在finally块中正确关闭数据库资源,因此DB用完了资源,这导致连接,准备语句和/或执行查询失败。 With proper exception handling this should already be hinted in the server logs. 使用适当的异常处理,应该已经在服务器日志中暗示了这一点。 Here's a basic kickoff example how to write JDBC code the proper way. 这是一个基本的启动示例,说明如何以正确的方式编写JDBC代码。 The normal practice is to acquire and close the database resources in shortest possible scope: 通常的做法是在尽可能短的范围内获取和关闭数据库资源:

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;
}

Any exception on close() can be ignored, but I prefer to log them so that you don't lost any evidence of a failure anywhere, even if it's minor. 可以忽略close()上的任何异常,但是我更喜欢将它们记录下来,以使您在任何地方都不会丢失任何失败的迹象,即使它很小。

This could be a database time-out related issue. 这可能是与数据库超时有关的问题。 Maybe you're databases have different time-out times? 也许您的数据库有不同的超时时间? Do you use connection pooling ? 您是否使用连接池 (you should!) Is the pool setup identical for both connections? (您应该!)两个连接的池设置是否相同? Are the databases configured to have time-out bigger than you're pool time-out values? 数据库是否配置为具有比您池超时值更大的超时值? Have you set autoReconnect=true in the connection parameter? 您是否在连接参数中设置了autoReconnect = true?

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

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