Golang: использование systemd для перезапуска и развертывания с нулевым временем простоя
22 декабря 2022 г.Во время перезапуска ваш API может быть недоступен в течение короткого периода времени, чтобы остановить старый экземпляр приложения и запустить новый. Это можно исправить, добавив еще одно приложение (прокси), которое прослушивает данные от имени основного приложения и каким-то образом передает данные основному приложению.
Популярный способ сделать это — передать прослушивающий сокет в качестве файлового дескриптора дочернему процессу, а затем повторно создать там сокет с помощью дескриптора. Systemd может сделать это за вас с помощью функции под названием активация сокета.
Настроив сокет systemd, вы можете указать systemd прослушивать настроенные порты и запускать службу с копией прослушиваемых сокетов. При перезапуске данные не теряются, а сохраняются в буферах ОС.
Системный сокет
Вы можете настроить сокет systemd, создав файл /lib/systemd/system/myapp.socket
, например, следующий сокет прослушивает порт 80, но вы можете добавить столько портов, сколько вам нужно:
[Socket]
ListenStream = 80
#ListenStream = 443
BindIPv6Only = both
Service = myapp.service
[Install]
WantedBy = sockets.target
Вам также необходимо настроить сопутствующий сервис systemd, создав файл myapp.service
:
[Unit]
Description = myapp
After = network.target
[Service]
Type = simple
ExecStart = /bin/myapp
ExecStop = /bin/kill $MAINPID
KillMode = none
[Install]
WantedBy = multi-user.target
Использование сокетов Systemd
Приложение Go следует изменить так, чтобы оно использовало сокет systemd вместо прямого прослушивания порта. Давайте установим модуль Go, который поможет нам в этом:
go get github.com/coreos/go-systemd/v22
А затем используйте его следующим образом:
import "github.com/coreos/go-systemd/v22/activation"
func main() {
listeners, err := activation.Listeners()
if err != nil {
return err
}
httpLn := listeners[0]
//httpsLn := listeners[1]
httpServer := &http.Server{
ReadHeaderTimeout: 5 * time.Second,
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
IdleTimeout: 60 * time.Second,
Handler: router,
}
if err := httpServer.Serve(httpLn); err != nil {
log.Printf("Serve failed: %s", err)
}
}
В качестве маршрутизатора Golang вы можете попробовать бунроутер.
Перезапуск приложения
Во-первых, вам нужно запустить настроенный сокет systemd:
sudo systemctl start myapp.socket
А затем проверьте, что сокет был успешно создан:
sudo systemctl status myapp.socket
Systemd автоматически запустит службу по первому запросу или в случае сбоя службы. Вы также можете вручную перезапустить службу во время развертывания:
sudo systemctl restart myapp.service
Отслеживание
Uptrace – это конкурент DataDog с открытым исходным кодом, который предлагает интуитивно понятный конструктор запросов, подробные информационные панели и правила оповещения. и интеграции для большинства языков и фреймворков. Он может обрабатывать миллиарды диапазонов и метрик на одном сервере и позволяет отслеживать ваши приложения в 10 раз дешевле.
Uptrace использует базу данных ClickHouse для хранения трассировок, метрик и логов. Вы можете использовать его для мониторинга приложений и настройки автоматических оповещений для получения уведомлений по электронной почте, Slack, Telegram и т. д.
Вы можете начать работу с Uptrace, загрузив пакет DEB/RPM или предварительно скомпилированный двоичный файл Go.
Также опубликовано здесь
Оригинал