Скрипты запускаемых служб в Linux располагаются в /etc/rc.d/init.d. Для того, чтобы скрипт запускался автоматически во время запуска системы, надо создать символическую ссылку на скрипт и разместить её в каталоге /etc/rc.d/rcN.d где N соответствует уровню выполнения скрипта.
Уровни инициализации Linux | Обозначиние |
0 | остановка системы (halt) — работа системы должна быть прекращена |
1 | однопользовательский режим работы — система инициализирует минимум служб и даёт единственному пользователю (как правило, суперпользователю) без проведения аутентификации командную строку. Как правило, этот режим используется для восстановления системы |
2 | многопользовательский режим — пользователи могут работать на разных терминалах, вход в систему с процессом аутентификации |
3 | многопользовательский сетевой режим — в отличие от предыдущего уровня, осуществляется настройка сети и запускаются различные сетевые службы; |
4 | не имеет стандартного толкования и практически не используется |
5 | запуск графической подсистемы — по сравнению с уровнем 3 производится также старт графической подсистемы X11, и вход в систему осуществляется уже в графическом режиме |
6 | перезагрузка системы — при включении этого режима останавливаются все запущенные программы и производится перезагрузка |
Чаще всего во время загрузке система использует уровни загрузки 3 или 5. Однако есть некоторая хитрость в названии самой символической ссылки, о которой многие умалчивают, и о которой я хочу рассказать.
Init.d
Например: /etc/rc.d/rc0.d/K60crond и /etc/rc.d/rc3.d/S40crond,
указывающие на один скрипт /etc/init.d/crond службы системного журнала. Скрипт, начинающийся с «K» соответствует останову службы, а «S» — запуску. Числа, следующие перед именем службы задают порядок запуска скриптов в директории. Например, скрипт /etc/rc.d/rc3.d/S34syslogd будет запущен до скрипта /etc/rc.d/rc3.d/S40crond, тогда как /etc/rc.d/rc3.d/K60crond до /etc/rc.d/rc3.d/K66syslogd. Можно заметить, что сумма чисел для одной службы равна 100 — это позволяет упорядочить все скрипты в порядке старта, обратном порядку завершения. Создавать самому символические ссылки весьма утомительно, и для этого лучше использовать специальную утилиту chkconfig.
Синтаксис её использования весьма прост:
1 2 3 4 |
chkconfig --list [имя сервиса] chkconfig --add <имя сервиса> chkconfig --del <имя сервиса> chkconfig [--level <уровни>] <имя сервиса> <on|off|reset|resetpriorities> |
Где имя сервиса — это имя исполняемого скрипта находящегося в /etc/rc.d/init.d
Однако и тут есть небольшая хитрость, дело в том, что скрипт запуска
должен иметь специальный формат, например такой:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#!/bin/bash # liferayd Init script for running Liferay Java portal # chkconfig: - 92 02 # description: Liferay Portal is the leading open source portal for the enterprise, \ # offering content management, collaboration, and social out-of-the-box. if [ -f /etc/init.d/functions ] ; then . /etc/init.d/functions elif [ -f /etc/rc.d/init.d/functions ] ; then . /etc/rc.d/init.d/functions else exit 0 fi PATH=/usr/bin:/sbin:/bin:/usr/sbin export PATH LRHOMEDIR="/opt/local/portal/" start(){ printf "Starting Portal\r" su - user -c "cd ${LRHOMEDIR}; ant start-portal" if [ $? -eq 0 ] ; then logger -t liferayd Portal build successfully else logger -t liferayd Portal build unsuccessfully fi } stop(){ printf "Stoping Portal\r" su - liferay -c "cd ${LRHOMEDIR}; ant stop-portal-force" if [ $? -eq 0 ] ; then logger -t liferayd Portal closed successfully else logger -t liferayd Portal closed unsuccessfully fi } restart(){ printf "Restarting Portal\r" stop start } case "$1" in start ) start ;; stop) stop ;; restart) restart ;; *) printf "Usage $0 {start|stop|restart}\n" ;; esac |
Скрипт должен иметь как минимум 3 возможных ключа запуска :
- start
- stop
- restart
именно эти основные команды используются для запуска, остановки и перезапуска.
В самом начале файла пишутся цифры отвечающие за последовательность запуска:
# chkconfig: — 92 02
Где 92 это номер в последовательности запуска, а 02 это номер последовательности остановки.
Чтоб добавить скрипт в автозагрузку надо:
- Создать исполняемый скрипт по шаблону приведёному выше
- Разместить исполняемый скрипт в /etc/init.d
- Выполнить команду chkconfig —add исполняемый_скрипт
- Выполнить команду chkconfig исполняемый_скрипт on
Вот и все, теперь при запуски системы наш портал будет сам запускатся
Systemd
Конфигурация состоит из файлов, которые называются юнитами. Все юниты находятся:
/usr/lib/systemd/system/ – юниты из установленных пакетов RPM
/run/systemd/system/ — юниты, созданные в рантайме
/etc/systemd/system/ — юниты, созданные системным администратором
Юнит представляет из себя текстовый файл:
[Название]имя_переменной = значение
Для создания юнита надо описать три секции: [Unit], [Service], [Install]
В секции Unit описываем:
Описание юнита:
Description=Liferay
Далее следует блок переменных, которые влияют на порядок загрузки сервисов:
After=mysql.service
Для запуска сервиса необходим запущенный mysql:
Requires=mysql.service
Для запуска сервиса желателен запущенный nginx:
Wants=nginx.service
Если сервис есть в Requires, но нет в After, то наш сервис будет запущен параллельно с требуемым сервисом
В секции Service указываем как надо запускать сервис:
Тип сервиса:
Type=simple
systemd предполагает, что служба будет запущена незамедлительно. Процесс при этом не должен разветвляться.
Type=forking
systemd предполагает, что служба запускается однократно и процесс разветвляется с завершением родительского процесса.
Также следует определить PIDFile=, чтобы systemd могла отслеживать основной процесс:
PIDFile=/var/run/liferay.pid
Рабочий каталог, он становится текущим перед запуском стартап команд:
WorkingDirectory=/opt/local/liferay
Пользователь и группа:
User=liferay
Group=liferay
Переменные окружения:
Environment=SERVER=production
Запрет на убийство сервиса вследствие нехватки памяти и срабатывания механизма OOM:
-1000 полный запрет , -100 понизим вероятность.
OOMScoreAdjust=-100
Команды на старт/стоп и перезапуск сервиса
ExecStart=/sbin/ant start-portal
ExecStop=/sbin/ant stop-portal-force
ExecReload=/sbin/ant stop-portal-force start-portal
Тут есть тонкость — systemd настаивает, чтобы команда указывала на конкретный исполняемый файл. Надо указывать полный путь.
Таймаут в секундах, сколько ждать system отработки старт/стоп команд.
TimeoutSec=300
Попросим systemd автоматически рестартовать наш сервис, если он вдруг перестанет работать.
Контроль ведется по наличию процесса из PID файла
Restart=always
В секции [Install] опишем, в каком уровне запуска должен стартовать сервис
Уровень запуска:
WantedBy=multi-user.target
multi-user.target или runlevel3.target соответствует нашему привычному runlevel=3
Unit для systemd готов:
liferay.service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
[Unit] Description=Liferay After=mysql.service Requires=mysql.service Wants=nginx.service [Service] Type=forking PIDFile=/var/run/liferay.pid WorkingDirectory=/opt/local/liferay User=liferay Group=liferay Environment=SERVER=production OOMScoreAdjust=-100 ExecStart=/sbin/ant start-portal ExecStop=/sbin/ant stop-portal-force ExecReload=/sbin/ant stop-portal-force start-portal TimeoutSec=300 [Install] WantedBy=multi-user.target |
Кладем этот файл в каталог /etc/systemd/system/:
1 2 3 4 5 6 |
systemctl status liferay myunit.service - liferay Loaded: loaded (/etc/systemd/system/liferay.service; disabled) Active: inactive (dead) |
1 2 |
systemctl enable liferay systemctl -l status liferay |
Если все впорядке— то вывод будет вот такой:
1 2 3 4 |
myunit.service - liferay Loaded: loaded (/etc/systemd/system/liferay.service; enabled) Active: inactive (dead) |
Запускаем сервис:
1 |
systemctl start liferay |
Смотрим статус:
1 |
systemctl -l status liferay |
Перегружаем демон systemd:
1 |
systemctl daemon-reload |