Сервлет перестает работать на сервере Tomcat после некоторых обращений или времени - PullRequest
2 голосов
/ 20 мая 2010

У меня очень странная проблема с некоторыми из моих сервлетов. Ниже моя конфигурация:

  • В папке A есть X сервлетов, развернутых в каталоге Tomcat
  • Папка B содержит Y сервлетов, развернутых в каталоге Tomcat

После определенного количества времени или попаданий в любой из сервлетов в папке B он перестает работать должным образом, тогда как в то же время все сервлеты в папке A работают нормально.

Я не могу отследить, где я совершаю ошибку.

Все кодировки для сервлетов обеих папок одинаковы, с той лишь разницей, что они взаимодействуют с разными БД, но это очень простая операция только для чтения с БД.

Есть идеи?

Ответы [ 3 ]

1 голос
/ 25 мая 2010

Проблема связана с регистратором. Экземпляр Logger не освобождается неявно, когда поток завершает выполнение, и поскольку нет очевидного метода, такого как close () для закрытия экземпляра Logger, поток doGet / doPost не завершается должным образом.

Избавление от Logger или, наоборот, явное уничтожение экземпляра / присвоение ему значения null решит проблему.

0 голосов
/ 21 мая 2010

Это может быть проблема с тайм-аутом базы данных. Может быть, у вас в базах данных разные времена ожидания? Используете ли вы пул соединений ? (Вы должны!) Идентична ли настройка пула для обоих соединений? Базы данных настроены так, чтобы время ожидания превышало значения времени ожидания пула? Вы установили autoReconnect = true в параметре соединения?

0 голосов
/ 21 мая 2010

Две важные вещи, которые нужно проверить при возникновении подобных проблем:

  1. Чтение журналов сервера для любых исключений и трассировки стека. В Tomcat он находится в папке /logs. Если вы их нашли, то они должны предоставить достаточно информации, чтобы решить проблему самостоятельно. Но если вы не понимаете причину, вам нужно обновить свой вопрос, чтобы включить соответствующие исключения и трассировки стека. Таким образом, мы можем помочь объяснить причину, чтобы решение было достаточно очевидным.

  2. Убедитесь, что код нигде не поглощает важные исключения. То есть вам нужно хотя бы отбросить или войти их после ловли. Например. таким образом не :

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

    Но более того:

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

    Или не менее :

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

    Таким образом, они будут зарегистрированы в журналах сервера.

Одна из первых вещей, которая приходит на ум в вашем конкретном случае, заключается в том, что код не закрывает ресурсы базы данных должным образом в блоке finally, и, таким образом, в базе данных заканчиваются ресурсы, что приводит к ошибке соединения, подготовки оператора и / или выполнение запроса. При правильной обработке исключений это уже должно быть указано в журналах сервера. Вот базовый пример того, как правильно написать код 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() можно игнорировать, но я предпочитаю регистрировать их, чтобы вы нигде не потеряли никаких признаков сбоя, даже если он незначительный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...