2009-09-24 1 views
3

Какова наилучшая практика при работе с ошибками в серверном приложении?Обработка ошибок (например, OutOfMemoryError) на серверах

В частности, как, по вашему мнению, приложение должно обрабатывать ошибки, такие как OutOfMemoryError?

Меня особенно интересуют приложения Java, работающие в Tomcat, но я думаю, что это более общая проблема.


Причина, почему я спрашиваю, потому что я рассматриваю веб-приложение, которое часто бросает OOME, но обычно он просто регистрирует их, а затем приступает к исполнению. Это приводит, очевидно, к большему количеству OOME.

Хотя это, безусловно, плохая практика, на мой взгляд, я не совсем уверен, что остановка сервера будет лучшим решением.

ответ

2

Существует не так много вы можете сделать, чтобы исправить OutOfMemoryError за исключением, чтобы очистить код и настроить память виртуальной машины Java (но если у вас есть утечка где-то это просто бинт)

Если у вас нет доступа к исходный код и/или не хотят его исправлять, внешнее решение - использовать какую-то программу для просмотра часов, которая будет контролировать приложение Java и автоматически перезапускать его при обнаружении OOME. Вот ссылка на один такой program.

Конечно, предполагается, что приложение выдержит перезагрузку.

1

Ну, если у вас ОМЕЮ, тогда лучшим способом было бы освободить как можно больше ресурсов (особенно кешированных). Перезагрузка веб-приложения (в случае сбоя веб-приложений) или самого веб-сервера (в случае, если что-то еще на сервере делает это), для восстановления из этого состояния. На фронте разработки, хотя было бы неплохо профилировать приложение и посмотреть, что занимает пространство, иногда есть ресурсы, которые привязаны к переменной класса и, следовательно, не собираются, иногда что-то еще. Раньше у нас были проблемы, когда Tomcat не выпускал классы предыдущих версий того же приложения, когда вы заменяете приложение более новой версией. В некотором роде проблема решена путем аннулирования переменных класса или повторного факторинга, чтобы не использовать их вообще, но некоторые утечки все еще оставались.

0

Я не эксперт в таких вещах, но я воспользуюсь возможностью дать свое смутное мнение по этой проблеме.

Вообще, я считаю, что есть два основных способа:

  1. сервер остановлен.
  2. Ресурсы, таким образом, изящно снижают пропускную способность, уменьшая потребление памяти, но сохраняя при этом жизнь. Думаю, для этого случая приложение должно иметь соответствующую архитектуру.
0

Согласно Javadoc о java.lang.Error:

Error является подклассом Throwable, что указывает на серьезные проблемы, которые разумное приложение не должно попытаться поймать. Большинство таких ошибок являются ненормальными условиями. Ошибка ThreadDeath, хотя и является «нормальным» условием, также является подклассом Error, потому что большинство приложений не должны пытаться его поймать.

метод не обязан заявить в своей статье throws любых подклассы Error, которые могут быть выброшены во время выполнения метода, но не пойманы, так как эти ошибки являются ненормальными условиями, которые никогда не должно происходить.

Таким образом, наилучшая практика при работе с подклассами Error заключается в том, чтобы устранить проблему, которая вызывает их, а не «обрабатывать» их. Как ясно сказано, они никогда не должны встречаться.

В случае с OutOfMemoryError возможно, у вас есть процесс, который потребляет много памяти (например, генерирует отчеты), а ваш JVM не имеет нужного размера, возможно, у вас есть утечка памяти где-то в вашем приложении и т. Д. Что бы это ни было , найдите проблему и исправьте ее, не обрабатывайте ее.

+2

Правильно, теоретически и очень неправильно на практике. В серверном приложении, где каждая минута простоев стоит реальных денег, вы делаете все возможное, чтобы обрабатывать * каждую ошибку, потому что исправление не то, что вы можете сделать немедленно (но, конечно, делать это как можно скорее, поэтому ошибка должна включать отправку некоторых срочных уведомлений), но упущенные возможные издержки * * начинаются немедленно. –

+1

Конечно, отправка уведомления - это хорошо, но это не должно быть реализовано в приложении, это проблема контроля/мониторинга. Затем, если вам нужна высокая доступность (т. Е. Нет простоя), запустите кластер, а не один экземпляр сервера приложений. Наконец, ОП просят о лучшей практике, и я считаю, что наилучшей практикой является устранение проблемы, а не ее обработка или отправка уведомления об этом. –

+0

Я бы сказал, что лучшая практика - это сделать как можно больше. Запуск кластера увеличивает стоимость и сложность непропорционально. –

2

Приложение не должно обрабатывать OOM вообще - это должно быть ответственностью сервера.

Следующий шаг: проверьте правильность настроек памяти. Если это не так, исправьте их; если они есть, исправьте приложение. :)

+0

Что вы подразумеваете под «сервером»? Аппаратное обеспечение или ОС не могут ничего сделать, но сервер приложений может. Если приложение не запускается внутри сервера приложений, оно должно обрабатывать эту ошибку. –

+0

@ Майкл, я имел в виду сервер приложений (который Tomcat, чтобы судить по OP). – gustafc

1

OutOfMemoryError отнюдь не всегда невосстанавливается - это может быть результатом одного плохого запроса, и в зависимости от структуры приложения он может просто отказаться от обработки запроса и продолжить обработку других без каких-либо проблем.

Итак, если ваша архитектура поддерживает его, поймайте ошибку в той точке, где у вас есть шанс прекратить делать то, что вызвало ее, и продолжить делать что-то еще - для сервера приложений это будет в том смысле, что отправляет запросы отдельным пользователям приложения.

Конечно, вы также должны убедиться, что это не остается незамеченным, и реальное исправление может быть реализовано как можно скорее, поэтому приложение должно зарегистрировать ошибку И отправить какое-то предупреждение (например, электронную почту, но предпочтительно что-то труднее игнорировать или заблудиться). Если во время этого что-то пойдет не так, то , а затем закрытие - единственная разумная вещь, которую нужно сделать.

1

@Michael Borgwardt, Вы не можете восстановиться после OutOfMemoryError на Java. Для других ошибок это может не остановить приложение, но OutOfMemoryError буквально висит приложения.

1

В нашем приложении, которое имеет дело с документами в большой степени, мы обнаруживаем ошибки OOM, когда один плохой запрос может привести к OOM, но мы не хотим сбивать приложение из-за этого. Мы ловим OOM и регистрируем его. Не уверен, что это лучшая практика, но кажется ее работающей

0

Я категорически не согласен с тем, что вы никогда не должны обращаться с OutOfMemoryError.

Да, в большинстве случаев он невосстанавливается. Однако один из моих серверов получил несколько дней назад, и сервер по-прежнему в основном работал более полутора часов. Никто не жаловался, поэтому я не заметил, пока мое программное обеспечение для мониторинга не получило сбой и через полтора часа после первого OutOfMemoryError. Мне нужно знать как можно скорее, когда на моем сервере есть OutOfMemoryError. Мне нужно обработать его, чтобы я мог настроить уведомление, чтобы узнать, как перезагрузить мой сервер как можно скорее.

Я все еще пытаюсь выяснить, как заставить Tomcat что-то делать, когда он получает ошибку. error-page, похоже, не работает для него.

Смежные вопросы