Как я должен запустить свой процесс Голанга в фоновом режиме?
Этот вопрос не связан строго с программированием, но, безусловно, важно для программистов.
Я написал простой smtp-сервер, когда я запускаю его с консоли, все в порядке, за исключением того, что он блокирует командную строку.
Я знаю, что могу запустить его через
nohup ... &
или через экран /tmux и т.д.
Но вопрос в том, как мне реализовать свою программу, которую он запускает в фоновом режиме, и системному администратору будет приятно настроить его и управлять процессом?
Некоторые ребята с гораздо большим опытом, чем я, на golang-nuts, писали, они не используют fork и т.д., и используют некоторые "обертка" в форме от monit и т.д.
Целевая платформа основана на Debian, все остальные элементы на ней основаны на init.d.
Любые хорошие ресурсы для этой темы или источников хорошо написанного примера проекта?
Ответы
Ответ 1
Как отметил Ник Supervisord, это отличный вариант, который также хорошо зарекомендовал себя в моем опыте.
Ник упомянул о проблемах, связанных с разветвлением - он отлично работает AFAICT. Проблема заключается не в том, чтобы разблокировать, но удалить привилегии. Из-за того, как запущенная среда Go запускает пул потоков, в котором goroutines мультиплексируются (когда GOMAXPROX > 1), setuid systemcall не является надежным способом удаления разрешений.
Вместо этого вы должны запустить свою программу как непривилегированный пользователь и использовать утилиту setcap, чтобы предоставить ему необходимые разрешения.
Например, чтобы разрешить привязку к пропуску с низким номером порта (например, 80), необходимо запустить setcap один раз в исполняемом файле: sudo setcap 'cap_net_bind_service=+ep' /opt/yourGoBinary
Вам может потребоваться установить setcap: sudo aptitude install libcap2-bin
Ответ 2
Уже есть хорошие ответы, но я добавлю дополнительную информацию.
Вам не нужно устанавливать дополнительное программное обеспечение, такое как supervisord
на Debian, чтобы заботиться о фоновой обработке процесса.
Debian поставляется с инструментом под названием start-stop-daemon
, который является стандартным способом запуска демонов в сценариях init.d
. Он также может также поставить процесс в фоновом режиме для вас, если программа не делает это самостоятельно. Посмотрите параметр --background
.
Используйте /etc/init.d/skeleton
как основу вашего init script, но измените функцию do_start()
следующим образом:
start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile \
--background --exec $DAEMON --test > /dev/null \
|| return 1
start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile \
--background --exec $DAEMON -- $DAEMON_ARGS \
|| return 2
Я также добавил параметр --make-pidfile
, который создает для вас файл PID.
Если вам нужно безопасно переключиться на другого пользователя, есть также --chuid
.
В Ubuntu и RHEL/CentOS/SL 6.X самым простым способом является создание файла конфигурации задания upstart
. Просто поместите exec /usr/sbin/yourprogram
в конфигурационный файл /etc/init/yourprogram.conf
. С выскочкой нет необходимости форсировать программу в фоновом режиме. Не добавляйте expect fork
или expect daemon
, которые вам нужны с традиционными демонами. С выскочкой лучше, если процесс не вилок.
Ответ 3
Я написал сообщение в блоге об этом некоторое время назад. Идея демонализации кажется мне неправильной, поскольку она оставляет вам много других вещей, о которых можно беспокоиться (например, что происходит, когда она терпит неудачу? Как вы управляете перезагрузкой процесса? Как вы обрабатываете ведение журнала, рабочий каталог, ядра, перезапуск системы, и т.д.)
Оказывается, если вы не пытаетесь все это сделать, все становится намного проще.
Ответ 4
Supervisord отлично работает для этого в моем опыте.
Вы пишете свое приложение для запуска в командной строке, печатных материалах и т.д., а supervisord заботится обо всех демонстрациях, перезапуске, если это не так, ограничение скорости и т.д. и т.д.
Я считаю, что разворачивание программ в фоновом режиме традиционным способом unix затруднено, потому что среда выполнения запускает некоторые потоки, прежде чем запускает вашу процедуру main()
Ответ 5
Но вопрос в том, как мне выполнить мою программу, которую он запускает в фоновом режиме, и системному администратору будет приятно настроить его и управлять процессом?
Несколько мыслей здесь.
Предоставить пакеты и репозиторий
Установка программного обеспечения - это одно, поддерживать и запускать это совершенно другая история. Конечно, я могу загрузить zip, распаковать его, поместить файлы в соответствующие каталоги (имейте в виду, что пакеты обычно разбросаны по всей файловой системе), создайте пользователя системы для запуска демона, установите соответствующие разрешения. Но эта утомительная, склонная к ошибкам (что приведет к большому притоку билетов, таких как "Бах! Не работает! Исправьте!" ) И вряд ли практично, если программное обеспечение будет установлено на многих системах.
Итак, нам нужен пакет, чтобы снизить уровень усыновления. Предоставление репозитория для этих пакетов обычно не является наукой о ракетах и упрощает установку и/или обновление. Существует различие между "Download- > Distribute- > Install/Update" и одной командой/сервером, например
$ awesomePm update coolApplication
Предоставьте хотя бы пакеты для систем RedHat и Debian. Лично я бы пошел на CentOS (что сделало бы ваш пакет совместимым практически с любыми дериваторами RHEL) и базовым Debian. Последнее должно сделать тривиальным предоставление пакета для Ubuntu. Поскольку я больше не использую Debian или производные, я не уверен, что они действительно совместимы, возникли проблемы при запуске, когда я в последний раз построил .deb
.
Предоставить правильную документацию. Документируйте, что установлено, где и почему. Предоставьте ссылки на соответствующую документацию. ссылки на ссылки на зависимости достаточны. Таким образом, вы можете настроить даже самого неопытного администратора для настройки вашего пакета.
Используйте самые защищенные, нормальные значения по умолчанию.
Особое примечание относительно golang. Большинство инструментов сборки пакетов разбивают двоичные файлы, содержащиеся в пакете, по умолчанию. Go не поддерживает это, поэтому будьте осторожны.
Быть полным
Нет ничего более раздражающего, чем неполный пакет.
Использовать syslog, если это вообще возможно, и придерживаться его условностей. Таким образом, ваши журналы будут помещены в места, где системный администратор ожидает их, и они заботятся о том, устарели ли они автоматически, не позволяя вашему приложению полностью запутать диски. Если системный администратор требует специальной обработки ваших журналов приложений, он настроит его таким образом.
Не поворачивайте журналы через ваше приложение. Это выбор пользователей, что делать с ними (что может иметь значение для их SLA). Даже если вы настроите порядок ведения журналов, они должны быть настроены, администратор должен узнать, как его настроить, что приводит к ненужной избыточности.
Если вам нужно записать в файл журнала, придерживайтесь политики ведения журнала целевой системы и предоставляйте файл конфигурации поворота журнала. Вы не хотите, чтобы приложение было причиной простоев только потому, что на компьютере закончилось дисковое пространство, не так ли?
Используйте системные инструменты вместо того, чтобы изобретать колесо. Если вашему приложению необходимо какое-то обслуживание, не беспокойтесь использовать планировщик внутри вашего приложения. Напишите специализированный инструмент для обслуживания (монолитные приложения - это "00" ) и используйте cron
. В частности, добавьте соответствующие файлы в один из каталогов /etc/cron*
.
Предоставить правильные сценарии инициализации!. Таким образом, администратор может использовать хорошо известные инструменты, такие как systemctl
, чтобы скомпилировать запуск и завершение работы вашего приложения. Это довольно раздражает, когда вы должны su
для пользователя или использовать sudo -u
для вызова оболочки script при запуске. Даже когда этот script называется @onboot
, отклонение от стандартов вызывает раздражение. Просто потому, что работает метод запуска, это не значит, что он должен использоваться.
Бонусные баллы за добавление профиля SE-Linux!
Разумеется, я часто видел неверно настроенные пакеты, поэтому: Проверьте свои пакеты! Начните с минимальной установки целевой ОС, установите свой пакет и убедитесь, что он запущен как и ожидалось. Проверьте каждую конфигурацию, которую вы предоставляете.
Если вы планируете разместить пакет в официальных репозиториях Debian, вы должны запланировать некоторое время: причина, по которой Debian стабильна, заключается в том, что требования к пакетам довольно жесткие, и даже когда вы выполняете все требования, у вас есть чтобы пройти весь путь от тестирования с помощью нестабильной до стабильной.
Быть точным
Не используйте существующих пользователей только потому, что это удобно. Если вы создаете веб-приложение, не используйте повторно пользователя "apache" или "www". Создайте пользователя, предназначенного для вашего пакета, и добавьте этого пользователя в соответствующие группы.
Соблюдайте принцип наименее необходимых разрешений.. Существует вряд ли причина иметь бинарный мир исполняемый файл, а тем более всемирно доступный для записи (который будет экстремальной дырой безопасности). То, что вы часто видите здесь в SO, если приложение не запускается, - это предложение установить разрешения для [0] 777, что позволяет каждому пользователю вносить какие-либо изменения в файл. На самом деле почти нет оснований делать двоичную запись доступной для любого пользователя: root, который все равно выполняет обновления, всегда может что-либо написать. Таким образом, разрешения должны быть 0550
для двоичных файлов. Этот принцип также применяется к каталогам данных и тому подобному. Потратьте немного времени и усилий здесь. Вы не хотите, чтобы ваше приложение было вектором успешной атаки, не так ли? Даже потенциальные риски безопасности, как правило, отражают вас и вашу репутацию. Я стараюсь установить все файлы данных на 0600
для файлов, которые должны быть записаны системным пользователем приложения, 0400
для файлов только для чтения и 0500
для двоичных файлов. Затем я делаю подробный анализ того, какие должны быть групповые разрешения. Например: группа может изменять отдельные шаблоны для веб-приложения, но скорее всего это не структура каталогов поддерева каталога ресурсов.
Если вы вложите усилия в безопасность, вы увеличите доверие. Имейте в виду, что пакеты часто проверяются на предмет их влияния на безопасность до принятия решения о том, что они приняты.
Придерживайтесь FHS (!!)! И даже тогда: только потому, что вы можете делать что-либо в /opt/yourapplication
, это не всегда хорошая идея. Скорее установите в /usr
и /var
соответственно (если ваше приложение не требуется во время загрузки).
Если у вас есть зависимости, определите их. Не просто предполагайте, что пакет присутствует.
Если у вас есть зависимость для локального SMTP-сервера, не объявляйте зависимость от postfix
. Возможно, администратор предпочитает sendmail (по любой причине, которая может быть). Поэтому определите зависимость от mail-transport-agent
(Debian) или mta
(RH, iirc).
Заключение
Это то, что я ожидаю от хорошего программного обеспечения - прекрасно сочетаюсь с существующим программным обеспечением и упрощает его установку, обслуживание, настройку и запуск, не изучая избыточную конфигурацию. Если я вижу профиль SELinux для пакета, это действительно дает поставщику бонус - если профиль не является крайне неаккуратным, это показывает, что поставщик очень серьезно относится к безопасности.