Для начала познакомимся с forever.
Запускаем терминал Linux, я использую Ubuntu.
Создаем каталог приложения, переходим в созданный каталог, создаем файл приложения Node.js.
В качестве редактора используем vim.
У кого vim не установлен:
- sudo apt-get install vim
Пишем код приложения:
var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('It will last forever!'); }).listen(3000, '127.0.0.1'); console.log('Server running at http://127.0.0.1:3000');
Устанавливаем forever:
- npm install forever
С целью исключения коллизий предпочитаю не устанавливать модули глобально.
Запускаем приложение с помощью установленного модуля forever:
- node_modules/forever/bin/forever start app.js
Тестируем:
А теперь предлагаю найти в списке запущенных процессов node для того, чтобы понять как устроен forever:
- ps axl | grep node
Становится понятно, что для обеспечения бесперебойной работы приложения forever запускает процесс,
который отслеживает событие падения целевого приложения, после наступления которого запускает приложение повторно. Где-то я это уже видел...
Выполним команду отображения списка процессов, запущенных forever:
- node_modules/forever/bin/forever list
Похоже forever ведет лог, что на мой взгляд вполне логично.
В завершение остановим все процессы, запущенные forever:
- node_modules/forever/bin/forever stop 0
Резюмируем: forever - очень полезный инструмент.
На просторах сети я нашел, как мне показалось, еще более "навороченный" инструмент - pm2, в свое время обязательно попробую.
Переходим к Windows. Где же я это уже видел?
Один мой товарищ арендует серверы Windows, на которых крутятся какие-то биржевые приложения. Не далее как прошло зимой мы пересекались по работе и он попросил меня написать скрипт, который поднимал бы эти самые биржевые приложения в случае падения - а падают они, надо сказать, нередко.
Я не стал париться с запуском приложений в качестве сервисов, а влегкую написал ему что-то типа:
Set objWMI = GetObject("winmgmts:\\.\Root\CIMV2") Set colEvents = objWMI.ExecNotificationQuery( _ "SELECT * FROM __InstanceDeletionEvent WITHIN 2 " & _ "WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name = 'notepad.exe'") Do Set objEvent = colEvents.NextEvent objWMI.Get("Win32_Process").Create("notepad.exe") Loop
Подобный код пришелся очень даже кстати, до сих пор никаких нареканий, только восторг и овации :).
Вспомнив описанный выше случай после знакомства с forever я решил написать чуть более сложный скрипт, который решает вопрос запуска приложений Windows, что называется, forever:
Сохраняем код в файл с расширением .vbs, я назвал его forever.vbs, запускаем блокнот:
Несколько раз пытаемся закрыть блокнот... что и требовалось.
Убиваем процесс мониторинга:
- taskkill /im wscript.exe /f
Закрываем блокнот. Читаем лог:
Вот как-то так. На этом прощаюсь. Покупайте наших слонов :)
Set args = WScript.Arguments ' проверяем наличие аргумента If args.Count = 0 Then WScript.Echo "Please enter process name" WScript.Quit() ElseIf args.Count > 2 Then WScript.Echo "Too much information" WScript.Quit() End If If args.Count = 1 Then Set f = New Forever If f.Run(args(0)) = 0 Then ' запускаем процесс WScript.Echo "Process '" & args(0) & "' is started, pid: " & f.pid mon = "wscript.exe " & WScript.ScriptFullName & " /pid:" & f.pid & " /proc:" & args(0) If f.Run(mon) = 0 Then ' запускаем процесс мониторинга WScript.Echo "Monitor started..." Else WScript.Echo "Failed to start process '" & mon & "'" End If Else WScript.Echo "Failed to start process '" & args(0) & "'" End If Set f = Nothing Else ' запускаем мониторинг If IsEmpty(args.Named.Item("pid")) Or IsEmpty(args.Named.Item("proc")) Then WScript.Echo "Named arguments are missing" WScript.Quit End If Set f = New Forever f.Monitor args.Named.Item("pid"), args.Named.Item("proc") End If Class Forever Private objWMI, m_pid, m_proc ' команда запуска процесса Public Property Get pid ' ProcessId запущенного процесса pid = m_pid End Property Private Sub Class_Initialize() Set objWMI = GetObject("winmgmts:\\.\Root\CIMV2") End Sub Private Sub Class_Terminate() Set objWMI = Nothing End Sub Public Function Run(proc) ret = objWMI.Get("Win32_Process").Create(proc, , , m_pid) If ret = 0 Then Log("Process '" & proc & "' started, pid: " & m_pid) Else Log("Failed to start process '" & proc & "'") End If Run = ret End Function Public Sub Monitor(pid, proc) m_pid = pid m_proc = proc Set colEvents = objWMI.ExecNotificationQuery( _ "SELECT * FROM __InstanceDeletionEvent WITHIN 2 " & _ "WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.ProcessId = '" & m_pid & "'") Do Set objEvent = colEvents.NextEvent Log("Process '" & m_proc & "' stopped, pid: " & m_pid) Do ret = Run(m_proc) WScript.Sleep 100 Loop Until ret = 0 ' пытаемся запустить процесс до победного Exit Do Loop Monitor m_pid, m_proc End Sub ' логгер Private Sub Log(s) Const logName = "forever.log" Set fso = CreateObject("Scripting.FileSystemObject") With fso path = .BuildPath(.GetParentFolderName(.GetFile(WScript.ScriptFullName)), logName) If Not .FileExists(path) Then Set fl = .CreateTextFile(path) fl.Close() Set fl = Nothing End If Set fl = .OpenTextFile(path, 8) With fl .WriteLine Now() & ": " & s .Close() End With Set fl = Nothing End With Set fso = Nothing End Sub End Class
Сохраняем код в файл с расширением .vbs, я назвал его forever.vbs, запускаем блокнот:
Несколько раз пытаемся закрыть блокнот... что и требовалось.
Убиваем процесс мониторинга:
- taskkill /im wscript.exe /f
Закрываем блокнот. Читаем лог:
Вот как-то так. На этом прощаюсь. Покупайте наших слонов :)