2010-06-16 3 views
5

Я недавно столкнулся с ошибкой, где умер всего приложения Erlang, получая сообщение журнала, который выглядел так:автоматический перезапуск приложений Erlang

=INFO REPORT==== 11-Jun-2010::11:07:25 === 
    application: myapp 
    exited: shutdown 
    type: temporary 

Я понятия не имею, что вызвало эту остановку, но реальная проблема, которую я что он не перезапустился. Вместо этого теперь пустая Erlang VM просто сидела там, ничего не делая.

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

Если я начинаю Supervisor в приложение, я могу сказать ему, чтобы сделать конкретный процесс временной или постоянной, и он будет автоматически перезапустить его для меня. Однако, согласно документации, если я делаю приложение временным или постоянным, оно не перезапускает его, когда оно умирает, а скорее убивает все остальные приложений.

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

(Я не говорю о реализации надзора над моим приложением, потому что тогда это уловка 22: что, если мой процесс диспетчера сработает? Я ищу какой-то API или настройку, которую я могу использовать для у меня есть монитор Erlang и перезагрузка моего приложения.)

Спасибо!

ответ

5

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

init(_Args) -> 
    {ok, {{one_for_one, 1000000, 1}, 
      [{ch3, {ch3, start_link, []}, 
      permanent, brutal_kill, worker, [ch3]}]}}.

(. Пример заимствован из OTP Design Principles User Guide)

+0

Отлично, спасибо за ваш ответ. Теперь я вижу, что причина, по которой она умерла, была действительно вызвана максимальным пределом перезапуска. Я не обязательно хочу просто отключить это, хотя, поскольку, если он действительно попадает в цикл перезапуска, нам может понадобиться перезапустить все приложение. Есть ли способ перезапустить приложение, если предел AllowedRestarts/MaxSeconds был удален, вместо того, чтобы отключить приложение? – Nick

+1

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

+0

Ссылка 404 - у кого есть обновление ....? – jisaacstone

4

Вы можете использовать heart перезапустить всю виртуальную машину, если она идет вниз, а затем использовать постоянный тип приложения, чтобы убедиться, что виртуальная машина завершает работу при ваше приложение завершает работу.

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

+0

Хорошо, спасибо. В этом случае такое решение будет работать отлично. Однако, если бы я хотел запустить сразу несколько приложений и перезапустить их самостоятельно по мере необходимости? Со всеми функциями контроля над процессом, которые входят в Erlang, я считаю удивительным, что я не могу сделать что-то просто, как перезапустить приложение, когда оно сходит вниз. – Nick

3

Используйте Monit, затем настройте приложение для завершения с помощью супервизора для всего приложения с разумной частотой перезапуска. Если приложение завершается, VM завершает работу, а monit перезапускает все.

Я никогда не смог бы получить Сердце, чтобы быть достаточно надежным, поскольку он только перезапускает виртуальную машину один раз, и это не очень хорошо работает с kill -9 виртуальной машины erlang.