Найти в Дзене
Артем Антонов

Запуск и завершение работы веб-сервера на Go

Оглавление

Стандартная библиотека Go предоставляет отличную основу для создания веб-серверов, однако, как показывает практика, часто требуется вносить изменения и дополнения. В этой статье я хотел бы рассмотреть процесс запуска веб-сервера и примеры его завершения.

Запуск веб-сервера

Чтобы веб-сервер или любая другая программа автоматически запускались после перезагрузки сервера Linux, можно использовать юниты systemd. Вот пример файла bot.service, который я использую для своего бота:

bot.service

Чтобы включить и запустить службу (юнит) в systemd, нужно скопировать файл, описывающий вашу службу, в каталог /etc/systemd/system/ и создать ссылку на этот файл в директории, которую systemd сканирует для активных служб.

sudo ln -s /etc/systemd/system/bot.service /etc/systemd/system/multi-user.target.wants/bot.service

Перезагружаем конфигурацию systemd:

systemctl daemon-reload

Запускаем сервис:

systemctl start bot

Проверим статус и убедимся что все работает:

systemctl status bot

Подробную информацию о параметрах systemd можно найти в документации: https://systemd.io/

Завершение работы веб-сервера

Рассмотрим два сценария для завершения работы сервера:

1. Обработчик URL-адреса для завершения работы

В процессе разработки часто используют простой, но не всегда оптимальный подход - реализация остановки сервера при переходе по определенному URL-адресу, например /kill или /shutdown. Следующий пример демонстрирует простую реализацию этого метода.

-2
main.go

Несмотря на простоту, этот подход имеет ряд недостатков:

  • При развертывании в production, URL-адрес должен быть заблокирован или удален. Использование одного и того же кода для разработки и эксплуатации может привести к ошибкам. Открытый URL-адрес для завершения работы сервера может позволить любому пользователю его отключить.
  • Обработчик запроса немедленно завершает работу сервера, прерывая обработку текущих запросов. Это может привести к потере данных или некорректному состоянию приложения.
  • Использование этого подхода обходит стандартные инструменты управления и развертывания. Рекомендуется использовать более надежные и управляемые способы остановки сервера.

2. Штатное завершение работы с помощью пакета manners

Для обеспечения корректного завершения работы сервера необходимо:

  • Прекратить прием новых запросов.
  • Сохранить данные на диск.
  • Завершить обработку открытых подключений.

Стандартный пакет http завершает работу немедленно и не предоставляет возможностей для выполнения этих действий. Это может привести к потере данных или некорректному состоянию приложения.

Для решения этой задачи можно использовать сторонний пакет, например github.com/braintree/manners. Пакет manners позволяет корректно завершить работу сервера, используя тот же интерфейс, что и функция ListenAndServe из стандартного пакета http.

-3
main.go

В этом примере используем пакет manners для запуска веб-сервера и перехватываем сигнал операционной системы (например, Interrupt) с помощью пакета signal.

При получении сигнала мы вызываем manners.Close(), который:

  • Прекращает прием новых подключений.
  • Дожидается завершения обработки текущих запросов.
  • Освобождает порт TCP, позволяя другим приложениям использовать его.

Преимущества:

  • Позволяет завершить текущие HTTP-запросы, не прерывая их обработку.
  • Останавливает прием новых запросов, освобождая порт TCP.
  • Обеспечивает более управляемый и предсказуемый процесс завершения работы сервера.

Ограничения:

  • Пакет manners работает только с HTTP-подключениями, а не с любыми TCP-соединениями.
  • В некоторых случаях может потребоваться реализовать свою логику для управления сопрограммами и ожидания их завершения перед выходом.

Этот подход обеспечивает более надежный и безопасный способ остановки сервера, минимизируя риск потери данных и обеспечивая корректную работу приложения.

Спасибо за ваше время и внимание! Ваша поддержка очень важна для меня! Если вам понравилась статья, пожалуйста, поставьте лайк!

Подпишитесь на мой Телеграм-канал, чтобы быть в курсе новых статей.

Удачи!