2015-01-03 4 views
1

Мне интересно, что было бы лучше всего использовать для развертывания обновлений для веб-приложения (MVC) Go. Представьте себе следующий сценарий:Лучшая практика обновления веб-приложения Go

1) Код и проверить некоторые изменения для моего веб-приложения Go

2) Deploy обновление без любого в настоящее время с помощью предыдущей версии получение прервана.

Я не знаю, как убедиться, что точка 2) может быть покрыта - когда кто-то отправляет запрос на сервер, и я перестраиваю его/перезапускаю только в этот момент, он получает ошибку - даже если запрос просто использует часть кода, который я не касался, или который обратно совместим, или если я просто добавил новый обработчик запросов.

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

ответ

1

Это вопрос не только с Go, но в целом можно разделить проблему на две отдельные из них:

  1. убедившись, что текущие запросы не получить прекращается и повлиять на пользовательский опыт.

  2. Убедитесь, что нет простоя, в котором нельзя обрабатывать новые запросы.

Первый легче решать: Вы просто не сильно убить ваш сервер, но сказать ему, чтобы выйти, вызывая «Drain фазу», в котором он не принимает новые запросы и только заканчивает текущие запросы и выходы. Это можно сделать, например, прослушивать сигналы и вводить приложение в специальное состояние.

Это не банально с Go, поскольку по умолчанию HTTP-сервер не поддерживает его закрытие, но вы можете запустить сервер с net.Listener, а затем сохранить ссылку на него, закрыть его, когда придет время.

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

Так что нам нужен другой экземпляр сервера, уже запущенного с новым кодом, в то время как старый не отвечает на новые запросы, не так ли? Это можно сделать несколькими способами:

  1. Имея более чем один сервер, и балансировки нагрузки на них сверху, позволяя (или более) сервера принять нагрузку, пока мы перезапустить другой. Это самый простой способ и то, как это делают большинство людей. Если вам нужны N серверов для загрузки ваших пользователей, просто держите N + 1 и перезапустите один за раз.

  2. Использование трюков для обмена гнездами. В новых ядрах Linux многие процессы могут прослушивать и принимать на одном и том же порту. То, что вы делаете, это просто запустить новый экземпляр, а затем сказать, что старый закончен и вышел. Таким образом, паузы нет. Это делается установкой SO_REUSEPORT на гнездо для прослушивания.

  3. выше может быть автоматизирован с готовыми к отправке решений, как Эйнхорн, который имеет дело со всеми деталями для вас, смотрите https://github.com/stripe/einhorn

  4. Другой подход описан в этом блоге: http://blog.nella.org/?p=879

+1

Это указывало мне в правильном направлении. 2 ссылки, которые я нашел, и которые, вероятно, будут полезны: https://github.com/mailgun/manners (изящное завершение работы) и, возможно, https://github.com/rcrowley/goagain (No-downtime-restart). – Compufreak

+1

@ Симпатичные манеры выглядят красиво. Я не думаю, что я буду использовать goagain лично, но скорее Einhorn или подход LB (который я использую в настоящее время). –

Смежные вопросы