Передача команд в запущенный сервис
Есть go программа (несколько сайтов, чат) запускаемая как systemd сервис. Писалась под обычный запуск через терминал с управлением через команды в терминале же.
for {
fmt.Scanln()
/*do something*/
}
Вопрос следующий: как в запущенный системд сервис передавать команды, чтобы они читались программой и происходило do something? Либо как переписать код чтобы слышать и слушать эти команды?
Также дико интересует вопрос как обращатся с этими командами прямо к программе в терминале без набора тысяч команд?
Отдельно хочу отметить, что для do something есть вывод для "неправильной" (нераспозананной) команды. И по логам (journalctl) при запуске он несколько (6) раз что-то туда отправляет что это может быть и что с этим делать?
Ответы (2 шт):
Есть несколько способов, но опишу самые простые. Выбирайте по усмотрению.
Использование http сервера. Да, добавляем в приложение обычный сервер, супер производительности тут не нужно. А дальше команды хоть curl, хоть браузером отправляются. А можно и свою супер тулу сделать. Простор для изобретательства - широчайший. Главное, что бы сервер наружу не торчал (то есть, для начала слушать хотя бы 127.0.0.1) и прикрутить примитивную авторизацию.
На файликах. Да, банально, да странно, но это работает. Просто время от времени (или используя inotify сервер следит за своими файлами. Если файл поменялся - можно что то сделать. Есть много подводных камней, но кто знает, может и так.
Классических линукс способ - использовать сигналы. В golang они завернуты в каналы, так что это может сильно упростить код. К сожалению, сигналов не так много и многие с них уже "расписаны" под конкретные задачи. Но sigusr1/sigusr2 можно повесить что то уникальное свое, а sighup сейчас часто используется как "перечитай свои конфиги".
Можно конечно использовать shared memory (но как по мне, это сильно пушкой по комарам) или pipe (но это те же сокеты, нужно делать свой протокол), но выбор всегда за писателем.
Чтоб не переписывать сервис вместо запускаемого файла подсунь такой скрипт
#!/bin/bash
/usr/bin/mkfifo /tmp/goservicefifo
/usr/bin/netcat --telnet --listen -p 9000 < /tmp/goservicefifo | /opt/goservice/bin/goservice > /tmp/goservicefifo
netcat будет слушать телнет на порту 9000 и к нему можно подключиться через putty или telnet и давать команды.
Правда она завершится при отключении от телнета. чуть позже напишу как сделать чтоб не завершался.