В CentOS, в отличии от Ubuntu, по умолчанию нет Start-stop-daemon для запуска своих процессов в виде демонов. При его наличии запуск приложения в виде демона решается простой командой (главное чтобы скрипт был исполняемым :)).
start-stop-daemon -Sbvx /home/redkin_p/bin/test.rb
Для того чтобы сделать это в CentOS (справедливо и для Debian) есть такие варианты:
0) Запустить приложение через nohup. Или в сессии screen/tmux (о screen).
nohup — UNIX-утилита, запускающая указанную команду с игнорированием сигналов потери связи (SIGHUP). Таким образом, команда будет продолжать выполняться в фоновом режиме и после того, как пользователь выйдет из системы. Позволяет не запускать start-stop-daemon, делать сервисы и вообще что-либо. Идет из коробки во всех известных дистрибутивах Linux.
Еще круто, что вывод она пишет в отдельный файл — nohup.out (если не нужен — можно дропнуть через редирект /dev/null) nohup bin/sms2.rb nohup nmap -sP 10.3.0.0/20 nohup ip netns exec VRF1 ping 172.17.0.2 >ping_res_va # по умолчанию STDOUT сохраняется в файле nohup.out
Написание демона, часть первая. Создание скрипта для демонизации.
1) собрать start-stop-daemon для CentOS. Как по мне очень плохое решение (но, возможно, в 2011 единственное) – требует компилятора, компиляции и прочих штук очень долгих и несущих существенные изменений в систему (зависимые системные библиотеки).
2) Сделать сервис в system.d. Прекрасное решение. Немного сложнее start-stop-daemon (и, тем более, nohup), но лучше т.к. позволяет стандартно добавить сервис в автозагрузку, следить по аналогии с другими сервисами за работоспособностью, стандартно перезагружать и прочее.
https://scottlinux.com/2014/12/08/how-to-create-a-systemd-service-in-linux-centos-7/ https://unix.stackexchange.com/questions/236084/how-do-i-create-a-service-for-a-shell-script-so-i-can-start-and-stop-it-like-a-d
Пошагово создание сервиса в system.d
1) Создаем файл с сервисом, называем как хотим, на конце должно быть “service”.
$ cat /etc/systemd/system/test_service.service [Unit] Description=test_service.rb [Service] Type=simple ExecStart=/usr/bin/test_service.rb [Install] WantedBy=multi-user.target
Для передачи переменных (напр. указываем название файла вывода от времени запуска сервиса) можно вызывать утилиту через /bin/bash. Пример: запускаем tcpdump, имя файла с дампом содержит дату/время запуска.
ExecStart=/bin/bash -c «test=$(/usr/bin/date | tr ‘ :’ ‘.’); /usr/sbin/tcpdump -n -w /opt/logs/$test.pcap»
2) Перезагружаем службу демонов
sudo systemctl daemon-reload
3) Стартуем наш сервис
sudo systemctl start test_service
4) Проверяем статус. Тут так же видим последние сообщения от нашей программы/скрипта. Для просмотра всех сообщений смотрим journalctl.
sudo systemctl status test_service sudo journalctl -u test_service
5) Добавляем в автозагрузку (можно так же использовать множество других способов, напр. добавив команду start сервиса в /etc/rc.local, но самый правильный через systemctl; offtop: при использовании rc.local нужно не забывать добавлять shebang и права на исполнение)
Что такое systemd? Управление демонами linux c помощью systemctl
sudo systemctl enable test_service
Posted on February 10, 2018 May 5, 2023 Author weril Categories Admin tasks, Coding, Linux
Leave a Reply Cancel reply
You must be logged in to post a comment.
Источник: weril.me
Запуск демона приложения через systemd
Серверные приложения, написанные, к примеру, на nodejs или на python, держат всегда запущенными. Если приложение вдруг упало, нужно его переподнять.
Кто-то запускает приложения через supervisor (написан на python) или pm2 (nodejs) — это такие демоны как раз для запуска приложений. Но на вашем сервере скорее всего уже есть systemd, который тоже умеет это делать. Зачем тогда устанавливать и настраивать supervisor или pm2?
Я не говорю о больших энтерпрайз-решениях, там свои инструменты для таких задач. Я говорю о небольших или хобби-проектах.
Рассмотрю запуск nodejs-приложения через systemd. Расскажу про перезапуск, ограничение прав и сбор логов.
Для примера попробую запустить такое приложение, написанное на nodejs:
const http = require(‘http’); // Get MYAPP_PORT from environment variable const MYAPP_PORT = process.env.
MYAPP_PORT; http.createServer((req, res) => if (req.
url === ‘/kill’) // App die on uncaught error and print stack trace to stderr throw new Error(‘Someone kills me’); > if (req.method === ‘POST’) // App print this message to stderr, but is still alive console.
error(`Error: Request $req.method> $req.url>`); res.
writeHead(405, ‘Content-Type’: ‘text/plain’ >); res.end(‘405 Method Not Allowed’); return; > // App print this message to stdout console.
log(`Request $req.method> $req.url>`); res.
writeHead(200, ‘Content-Type’: ‘text/plain’ >); res.end(‘200 OK’); >) .listen(MYAPP_PORT);
Этот скрипт запускает веб-сервер. Он слушает порт, который задан в переменной окружения MYAPP_PORT . Запущу приложение, чтобы проверить:
MYAPP_PORT=3000 node index.js
Приложение на все гет-запросы отвечает «200 OK»:
curl ‘http://localhost:3000’
На пост-запросы отвечает «405 Method Not Allowed»:
curl -X POST ‘http://localhost:3000’
И при запросе /kill вообще умирает:
curl ‘http://localhost:3000/kill’
Сервис-юнит
Systemd оперирует понятиями юнитов. Юнитом может быть процесс-демон, устройство, или даже список других юнитов. В руководстве man systemd в секции «Concepts» описано, какие есть типы юнитов, и для чего они нужны.
Мне понадобится самый первый — Service unit. Он позволяет запустить процесс в режиме демона и перезапускать процесс, если он упал. В руководстве man systemd.unit описано, как писать юниты в целом, а в man systemd.service — как писать сервис-юниты.
Файлы своих юнитов нужно класть в /etc/systemd/system/ . Я назову свой /etc/systemd/system/myapp.service . Минимальная конфигурация для сервиса может быть такая:
[Service] Environment=MYAPP_PORT=3000 ExecStart=/usr/local/bin/node /usr/local/www/myapp/index.js
В поле Environment нужные приложению переменные окружения. В ExecStart команда для запуска приложения. /usr/local/bin/node — это полный путь к nodejs, его можно узнать командой:
which node
А /usr/local/www/myapp/index.js — полный путь к моему приложению.
Пробую запустить сервис:
sudo systemctl start myapp.service
sudo systemctl status myapp.service ● myapp.service Loaded: loaded (/etc/systemd/system/myapp.service; static; vendor preset: enabled) Active: active (running) since Fri 2017-08-04 21:50:14 MSK; 5s ago Main PID: 3815 (node) Tasks: 6 Memory: 7.7M CPU: 80ms CGroup: /system.slice/myapp.service └─3815 /usr/local/bin/node /usr/local/www/myapp/index.js Aug 04 21:50:14 ubuntu16 systemd[1]: Started myapp.service.
Ну типа работает. Дёрну курлом, чтобы проверить:
curl ‘http://localhost:3000/’ 200 OK
Автоматический перезапуск
Если приложение по какой-то причине умрёт, то оно не поднимется. Вот я дёргаю убивающий эндпойнт:
curl ‘http://localhost:3000/kill’ curl: (52) Empty reply from server
И проверяю статус приложения:
sudo systemctl status myapp.service ● myapp.service Loaded: loaded (/etc/systemd/system/myapp.service; static; vendor preset: enabled) Active: failed (Result: exit-code) since Fri 2017-08-04 21:51:46 MSK; 5s ago Process: 3815 ExecStart=/usr/local/bin/node /usr/local/www/myapp/index.js (code=exited, status=1/FA Main PID: 3815 (code=exited, status=1/FAILURE) Aug 04 21:51:46 ubuntu16 node[3815]: ^ Aug 04 21:51:46 ubuntu16 node[3815]: Error: Someone kills me Aug 04 21:51:46 ubuntu16 node[3815]: at Server.http.createServer (/usr/local/www/myapp/index.js:1 Aug 04 21:51:46 ubuntu16 node[3815]: at emitTwo (events.js:106:13) Aug 04 21:51:46 ubuntu16 node[3815]: at Server.emit (events.js:191:7) Aug 04 21:51:46 ubuntu16 node[3815]: at HTTPParser.parserOnIncoming [as onIncoming] (_http_server Aug 04 21:51:46 ubuntu16 node[3815]: at HTTPParser.parserOnHeadersComplete (_http_common.js:99:23 Aug 04 21:51:46 ubuntu16 systemd[1]: myapp.service: Main process exited, code=exited, status=1/FAILUR Aug 04 21:51:46 ubuntu16 systemd[1]: myapp.service: Unit entered failed state. Aug 04 21:51:46 ubuntu16 systemd[1]: myapp.service: Failed with result ‘exit-code’.
Чтобы systemd переподнимал упавшее приложение, нужно добавить опцию Restart. У неё есть несколько значений, подробно описанных в man systemd.service . Значение always будет в любой ситуации перезапускать приложение:
[Service] Environment=MYAPP_PORT=3000 ExecStart=/usr/local/bin/node /usr/local/www/myapp/index.js Restart=always
Когда изменили файл юнита, надо заставлять systemd перечитать его, чтобы он использовал уже новый файл:
sudo systemctl daemon-reload
Снова запущу сервис, дёрну убивающую ручку и проверю, переподнимется ли приложение:
sudo systemctl start myapp.service curl ‘http://localhost:3000/kill’ curl: (52) Empty reply from server curl ‘http://localhost:3000/’ 200 OK curl ‘http://localhost:3000/kill’ curl: (52) Empty reply from server curl ‘http://localhost:3000/’ 200 OK
Ну вот. Теперь упавший процесс переподнимается.
Ограничение прав
Пользователя и группу, от имени которых будет запущен процесс, можно установить переменными User и Group:
[Service] Environment=MYAPP_PORT=3000 User=www-data Group=www-data ExecStart=/usr/local/bin/node /usr/local/www/myapp/index.js Restart=always
Запись и просмотр логов
Здорово, если ваше приложение пишет логи в файлы. Но если оно пишет в стандартный вывод, то через systemd можно собирать эти записи. По умолчанию они и так куда-то собираются.
Куда именно — зависит от ваших настроек. У меня например на Ubuntu 16.04 они сливаются в журнал systemd, и посмотреть их можно вот так:
journalctl -u myapp.service
или в файле /var/log/syslog .
Можно сделать, чтобы systemd направлял вывод процесса в syslog, и написать правила обработки логов для него. Например сливать их на сервер-агрегатор логов или просто писать в файлы.
[Service] Environment=MYAPP_PORT=3000 User=www-data Group=www-data ExecStart=/usr/local/bin/node /usr/local/www/myapp/index.js Restart=always # Отправка логов syslog StandardOutput=syslog StandardError=syslog SyslogIdentifier=myapp
Опции StandardOutput и StandardError определяют, куда писать вывод приложения. Возможные значения этих опций вы можете посмотреть в man systemd.exec . SyslogIdentifier собственно задаёт имя сервиса для syslog. Кстати, при отправке логов в syslog, в журнал systemd они тоже будут писаться, так что можно по-прежнему читать их с помощью journalctl.
Ну так вот, в syslog можно настроить правила обработки логов от вашего приложения. У меня в качестве syslog-демона rsyslog. Его настройки лежат в /etc/rsyslog.d/ . Создаю файл /etc/rsyslog.d/100-myapp.conf с таким содержимым:
$RepeatedMsgReduction off if $programname == ‘myapp’ then -/var/log/myapp/debug.log
$RepeatedMsgReduction off нужно, чтобы syslog несколько одинаковых сообщений не схлопывал в одно.
Systemd не умеет слать stdout и stderr в syslog с разным уровнем severity, поэтому в такой конфигурации нельзя писать stdout в один файл, а stderr в другой.
Можно направить stdoud процесса в логгер (утилита для записи в syslog) пайпом, а stderr слать через systemd:
[Service] Environment=MYAPP_PORT=3000 User=www-data Group=www-data # пайпим stdout в logger с тегом myapp ExecStart=/bin/sh -c ‘/usr/local/bin/node /usr/local/www/myapp/index.js | logger —tag myapp’ # stder шлём в syslog средствами systemd StandardError=syslog SyslogIdentifier=myapp # устанавливаем уровень логирования: err SyslogLevel=err Restart=always
И настроить в syslog правила для записи в разные файлы:
$RepeatedMsgReduction off if $programname == ‘myapp’ and $syslogseverity < 5 then -/var/log/myapp/error.log if $programname == ‘myapp’ and $syslogseverity >= 5 then -/var/log/myapp/debug.log
Кроме записи в файлы, можно конечно и на сервер-агрегатор слать.
Если вы пишете логи в файлы, не забудьте настроить logrotate. Пример файла конфигурации /etc/logrotate.d/myapp :
/var/log/myapp/debug.log /var/log/myapp/error.log < rotate 7 daily compress missingok notifempt postrotate invoke-rc.d rsyslog rotate >/dev/null endscript >
Самое главное тут — скрипт postrotate, который заставляет rsyslog переоткрыть файл после ротации. Подробности про настройку logrotate можно прочитать в man logrotate.conf
Вот так, с помощью нехитрых приспособлений приложение на nodejs (или на python) можно превратить в демон, который поднимется после падения, и логи которого нормально сохраняются и ротируются.
Подписывайтесь на телеграм-канал про фронтенд, дизайн, работу и жизнь.
Источник: isqua.ru
Что такое демоны в Linux
Демоны много работают, для того, чтобы вы могли сосредоточится на своем деле. Представьте, что вы пишите статью или книгу. Вы заинтересованны в том, чтобы писать. Удобно, что вам не нужно вручную запускать принтер и сетевые службы, а потом следить за ними весь день для того чтобы убедится, что всё работает нормально.
За это можно благодарить демонов, они делают эту работу за нас. В сегодняшней статье мы рассмотрим что такое демоны в Linux, а также зачем они нужны.
Что такое демоны в понятии Linux
Демон Linux — это программа, у которой есть определённая уникальная цель. Обычно, это служебные программы, которые незаметно работают в фоновом режиме для того чтобы отслеживать состояние и обслуживать определённые подсистемы и гарантировать правильную работу всей операционной системы в целом. Например, демон принтера, отслеживает состояние служб печати, а сетевой демон управляет сетевыми подключениями и следит за их состоянием.
Многие люди, перешедшие в Linux из Windows знают демонов как службы или сервисы. В MacOS термин «Служба» имеет другое значение. Так как MacOS это тоже Unix, в ней испольуются демоны. А службами называются программы, которые находятся в меню Службы.
Демоны выполняют определённые действия в запланированное время или в зависимости от определённых событий. В системе Linux работает множество демонов, и каждый из них предназначен для того чтобы следить за своей небольшой частью операционной системы. Поскольку они не находятся под непосредственным контролем пользователя, они фактически невидимы, но тем не менее необходимы. Поскольку демоны выполняют большую часть своей работы в фоновом режиме, они могут казаться загадочными.
Какие демоны работают на вашем компьютере
Обычно имена процессов демонов заканчиваются на букву d. В Linux принято называть демоны именно так. Есть много способов увидеть работающих демонов. Они попадаются в списке процессов, выводимом утилитами ps, top или htop. Но больше всего для поиска демонов подходит утилита pstree. Эта утилита показывает все процессы, запущенные в вашей системе в виде дерева. Откройте терминал и выполните такую команду:
Вы увидите полный список всех запущенных процессов. Вы можете не знать за что отвечают эти процессы, но они все будут здесь перечислены. Вывод pstree — отличная иллюстрация того, что происходит с вашей машиной. Здесь удобно найти запущенные демоны Linux.
Вот демоны Linux, которых вы можете здесь увидеть: udisksd, gvfsd, systemd, logind и много других. Список процессов довольно длинный, поэтому он не поместится в одном окне терминала, но вы можете его листать.
Запуск демонов в Linux
Давайте разберемся как запустить демона Linux. Ещё раз. Демон — это процесс, работающий в фоновом режиме и находится вне контроля пользователя. Это значит, что демон не связан с терминалом, с помощью которого можно было бы им управлять. Процесс — это запущенная программа.
В каждый момент времени он может быть запущенным, спящим или зомби (процесс выполнивший свою задачу, но ожидающий пока родительский процесс примет результат).
В Linux существует три типа процессов: интерактивные, пакетные и демоны. Интерактивные процессы пользователь запускает из командной строки. Пакетные процессы обычно тоже не связанны с терминалом. Они запускаются обычно во время когда на систему минимальная нагрузка и делают свою работу. Это могут быть, например, скрипты резервного копирования или другие подобные обслуживающие сценарии.
Интерактивные и пакетные процессы нельзя считать демонами, хотя их можно запускать в фоновом режиме и они делают определённую работу. Ключевое отличие в том, что оба вида процессов требуют участия человека. Демонам не нужен человек для того чтобы их запускать.
Когда загрузка системы завершается, система инициализации, например, systemd, начинает создавать демонов. Этот процесс называется forking (разветвление). Программа запускается как обычный интерактивный процесс с привязкой к терминалу, но в определённый момент она делится на два идентичных потока. Первый процесс, привязанный к терминалу может выполнятся дальше или завершится, а второй, уже ни к чему не привязанный продолжает работать в фоновом режиме.
Существуют и другие способы ветвления программ в Linux, но традиционно для создания дочерних процессов создается копия текущего. Термин forking появился не из ниоткуда. Его название походит от функции языка программирования Си. Стандартная библиотека Си содержит методы для управления службами, и один из них называется fork. Используется он для создания новых процессов.
После создания процесса, процесс, на основе которого был создан демон считается для него родительским процессом.
Когда система инициализации запускает демонов, она просто разделяется на две части. В таком случае система инициализации будет считаться родительским процессом. Однако в Linux есть ещё один метод запуска демонов. Когда процесс создает дочерний процесс демона, а затем завершается. Тогда демон остается без родителя и его родителем становится система инициализации.
Важно не путать такие процессы с зомби. Зомби, это процессы, завершившие свою работу и ожидающие пока родительский процесс примет их код выхода.
Примеры демонов в Linux
Самый простой способ определить демона — это буква d в конце его названия. Вот небольшой список демонов, которые работают в вашей системе. Каждый демон создан для выполнения определённой задачи.
- systemd — основная задача этого демона унифицировать конфигурацию и поведение других демонов в разных дистрибутивах Linux.
- udisksd — обрабатывает такие операции как: монтирование, размонтирование, форматирование, подключение и отключение устройств хранения данных, таких как жесткие диски, USB флешки и т д.
- logind — небольшой демон, управляющий авторизацией пользователей.
- httpd — демон веб-сервера, позволяет размешать на компьютере или сервере веб-сайты.
- sshd — позволяет подключаться к серверу или компьютеру удалённо, по протоколу SSH.
- ftpd — организует доступ к компьютеру по протоколу FTP для передачи файлов.
- crond — демон планировщика, позволяющий выполнять нужные задачи в определённое время.
Как появился термин демон в Linux
Так откуда же взялся этот термин? На первый взгляд может показаться, что у создателей операционной системы просто было искаженное чувство юмора. Но это не совсем так. Это слово появилось в вычислительной технике ещё до появления Unix. А история самого слова ещё более древняя.
Изначально это слово писалось как daimon и означало ангелов хранителей или духов помощников, которые помогали формировать характеры людей. Сократ утверждал, что у него был демон, который ему помогал. Демон Сократа говорил ему когда следует держать язык за зубами. Он рассказал о своем демоне во время суда в 399 году до нашей эры. Так что вера в демонов существует довольно давно.
Иногда слово daimon пишется как daemon. Это одно и то же.
В то время как daemon — помощник, demon — это злой персонаж из библии. Различия в написании не случайны и видимо так было решено где-то в 16-том веке. Тогда решили, что daemons — хорошие парни, а demons — плохие.
Использовать слово демон (daemon) в вычислительной технике начали в 1963 году. Проект Project MAC (Project on Mathematics and Computation) был разработан в Массачусетском технологическом институте. И именно в этом проекте начали использовать слово демон для обозначения любых программ, которые работают в фоновом режиме, следят за состоянием других процессов и выполняют действия в зависимости от ситуации. Эти программы были названы в честь демона Максвелла.
Демон Максвелла — это результат мысленного эксперимента. В 1871 году Джеймс Клер Максвелл представил себе существо, способное наблюдать и направлять движение отдельных молекул. Целью мысленного эксперимента было показать противоречия во втором законе термодинамики.
Однако есть и другие варианты значения этого слова. Например это может быть аббревиатура от Disk And Executive MONitor. Хотя первоначальные пользователи термина демон не использовали его для этих целей, так что вариант с аббревиатурой, скорее всего неверный.
Теперь вы знаете что такое демоны в понятии Linux. На завершение, обратите внимание, что талисман BSD — демон. Он выбран в честь программных демонов (daemons) но выглядит как злой демон (demon). Имя этого демона Beastie. Точно неизвестно откуда взялось это имя, но есть предположения, оно походит от фразы: BSD. Try it; I did. Если произнести это на английском быстро, получится звук похожий на Beastie.
А ещё тризуб Beastie символизирует разветвление (forking) процессов в Linux.
Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.
Источник: losst.pro