msrc
Унаследовано от "gitlab.systems-fd.com/packages/golang/servers/msrc/v3
Библиотека мультисервисного приложения для Golang
Библиотека предназначена для реализации мультисервисных приложений на Golang
.
Например: У вас есть сервис, который предоставляет RestAPI, а также требуется реализация
Websocket. По сути каждый сервис требует блокировки основной Go-routine
, можно использовать
дочерние go-routine
, что по сути и делает эта библиотека.
Также библиотека реализует Graceful shutdown
, который позволит правильно останавливать сервисы.
Сервис поддерживает логирование на основе github.com/sirupsen/logrus
Установка
Необходимо включить библиотеку в один из скриптов следующим образом:
import "gitlab.systems-fd.com/packages/golang/servers/msrc/v3"
Далее необходимо установить зависимости при помощи стандартной утилиты go get
:
go get -u gitlab.systems-fd.com/packages/golang/servers/msrc/v3
Использование
Для использования библиотеки необходимо реализовать интерфейс сервиса:
// ServiceInterface описывает интерфейс сервиса, для параллельного запуска.type ServiceInterface interface { // Run выполняет запуск сервера Run() error
// GracefulShutdown выполняет правильную остановку сервиса GracefulShutdown()
// IsStarted возвращает статус состояния запуска сервиса IsStarted() bool
// IsAlive возвращает статус сервиса: живой или нет IsAlive() bool}
Далее необходимо использовать фабрику для генерации объекта службы:
service := msrc.MultiService( map[string]multiservice.ServiceInterface{ "Test-Service": &service{}, },)
При передаче списка, ключ используется в качестве уникального названия сервиса.
После создания объекта сервиса необходимо его запустить:
err := service.Run()
В случае возникновения ошибки сервис остановит все подсервисы с использованием Graceful shutdown
и вернет возникшую ошибку.
Укороченный интерфейс сервиса
В библиотеку включена реализация функционала отслеживания статуса остановки и завершения
на основе контекста. Данный функционал входит в реализацию msrc.SimpleService
Данный сервис принимает на вход сервис с интерфейсом:
// SimpleService описывает интерфейс упрощенного сервиса, для библиотеки.// Данный сервис может быть использован в случаях, когда нет необходимости// внутри следить за флагами состояния. Сервис должен реализовывать лишь// функционал работы и правильной остановки.type SimpleService interface { // Run выполняет запуск упрощенной версии сервиса. // На вход передается контекст, который передаст `<-ctx.Done()` в случае // его остановки. Сам сервис должен обрабатывать его, если он не реализует // своего собственного, отдельного алгоритма остановки. Run(ctx context.Context) error
// GracefulShutdown выполняет правильную остановку упрощенного // сервиса. В данном случае, если сервис необходимо останавливать // вызовом отдельного функционала остановки, этот метод предоставляет // такую возможность. // // Метод вызывается в процессе остановки сервера и принимает на вход // контекст с deadline, устанавливаемым сверху. За установленное время // сервис либо завершает работу, либо отключается принудительно. GracefulShutdown(ctx context.Context) error}
Для превращения его в полноценный сервис необходимо использовать функцию msrc.SimpleService
.
Она обернет такой сервис в стандартную реализацию, которая позволит отслеживать Liveness Probe
на основе статуса работы сервиса, а так же останавливать его при помощи встроенного контекста,
который будет переключаться на <-ctx.Done()
при завершении работы.
Данный функционал позволяет так же реализовывать правильную остановку, если ваш сервис не поддерживает остановку через контекст.
В качестве последнего аргумента можно передать таймаут ожидания завершения работы функции. Логика работы следующая: либо сервис завершает работу за это время, либо разблокируем остановку, чтоб не ожидать дольше положенного времени. По умолчанию данный интервал ожидания - 5 секунд.
Если передать в качестве интервала ожидания 0, то таймаут ожидания составит 1000 часов, что по сути эквивалентно ожиданию реальной остановки сервиса.
HTTP сервер
В библиотеку включена поставка стандартного HTTP сервера в виде обертки для Multi Service.
Данная обертка принимает на вход хост и порт для HTTP сервера, а так же роутер, который
необходимо использовать для сервера. Роутер должен реализовывать стандартный интерфейс
http.Handler
.
Данный сервис так же позволяет переопределять стандартные параметры сервера. Для этого необходимо передать переопределение в качестве последнего аргумента фабрики.
// HttpService реализует фабрику сервиса для библиотеки, реализующего// функционал HTTP сервера. На вход передаются обязательные аргументы// для HTTP сервера, а так же возможна передача конфигурации запуска// сервера.//// Если конфигурация запуска не передана, то будет использоваться конфигурация// `http.Server{}`, при этом в обоих случаях (передано/не передано) будет// происходить переопределение полей Addr и Handler в соответствии с// переданными обязательными аргументами функции.func HttpService( HttpHost, HttpPort string, Router http.Handler, GraceStopPeriodSeconds uint8, ServerConfig ...*http.Server,) ServiceInterface
Реализация Liveness для Kubernetes
Для реализации данного функционала у каждого сервиса предусмотрено 2 метода:
// Возвращает статус состояния запуска сервисаIsStarted() bool
// Возвращает статус сервиса: живой или нетIsAlive() bool
Первый возвращает статус запуска сервера. Используется для Readyness Probe
Второй возвращает статус: жив ли сервис. Используется для Liveness Probe
По сути статусы всех сервисов суммируются и выдается итоговый результат как для readyness
,
так и для liveness
, поэтому если хотябы один сервис умрет, то liveness
не пройдут и будет
вызвана остановка пода.
Для настройки Kubernetes необходимо при инициализации сервиса передать порт прослушивания liveness:
service := multiservice.MultiService( map[string]multiservice.ServiceInterface{ "Test-Service": &service{}, }, 19000)
Если передано значение 0, то liveness не будет подключен. По умолчанию данный аргумент можно не передавать.
Для проверки используйте следующие url контейнера:
/ready - Readyness Probe
/alive - Liveness Probe