Назад | Перейти на главную страницу

служебный файл для приложения golang

Итак, я написал приложение golang, которое я хочу инициализировать systemd всякий раз, когда мой сервер перезагружается.

Вот служебный файл: -

[Unit]
Description=golang wiki initialization

[Service]
Type=forking
PIDFile=/tmp/gowiki.pid-3030
User=root
Group=root
WorkingDirectory=/var/www
ExecStart=/bin/bash -c 'daemonize -o stdout.log -e stderr.log /var/www/wiki'

[Install]
WantedBy=multi-user.target

Кажется, он работает хорошо всякий раз, когда я перезагружаю сервер, но я все еще сталкиваюсь с немного раздражающей проблемой, когда я вручную запускаю или перезапускаю gowiki вот так в терминале: -

systemctl start gowiki

или

systemctl restart gowiki

Это действительно запускает мой процесс gowiki; однако после того, как я выполню свой systemctl start gowiki Я завис в своем терминале, и кажется, что команда не завершается, пока я вручную не нажму Ctrl-C.

Что я делаю не так, чтобы вызвать эту проблему?

Это сработало.

[Unit]
Description=golang wiki initialization

[Service]
PIDFile=/tmp/gowiki.pid-4040
User=root
Group=root
WorkingDirectory=/var/www
ExecStart=/bin/bash -c '/var/www/wiki'

[Install]
WantedBy=multi-user.target

Поскольку Type=forking службы ожидают выхода родительской службы до ее фактического запуска. Если родитель никогда не завершает работу, то systemctl start не вернет вам приглашение, потому что не думает, что он завершился.

Если вы не против немного скорректировать свой код для systemd, самым чистым решением, которое я нашел до сих пор, является использование SDNotify-signal.

import "github.com/coreos/go-systemd/daemon"

func main() {
    // Important init stuff here
    ....

    // Notify systemd that we're ready
    sent, e := daemon.SdNotify(false, "READY=1")
    if e != nil {
        log.Fatal(e)
    }
    if !sent {
        log.Printf("SystemD notify NOT sent\n")
    }

    // And do something blocking like listening for HTTP(s)
  • В нем нет CGO-deps
  • Код также работает в системах, отличных от systemd (в этом случае он выдает предупреждение, которое не отправлено)
  • Если вам нужен рабочий пример: https://github.com/mpdroog/dnsleak

Ваш соответствующий unit-файл systemd:

[Unit]
Description=golang wiki initialization
After=network.target
Requires=network.target

[Service]
Type=notify

Restart=always
RestartSec=30
TimeoutStartSec=0

WorkingDirectory=/var/www
ExecStart=/var/www/wiki
User=www-data
Group=www-data
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target