Конфигурация веб-приложений для производства Golang

Для тех из вас, кто работает Go backends в производстве:

Каков ваш стек/конфигурация для запуска веб-приложения Go?

Я не видел многого в этой теме, кроме людей, использующих стандартный библиотечный net/http-пакет, чтобы поддерживать работу сервера. Я читаю, используя Nginx для передачи запросов на сервер Go - nginx с Go

Это кажется мне немного хрупким. Например, сервер не будет автоматически перезагружаться, если машина была перезапущена (без дополнительных скриптов конфигурации).

Есть ли более твердая производственная установка?

В стороне от моего намерения - я планирую использовать сервер back-сервера REST для моего следующего проекта и хочу убедиться, что Go будет жизнеспособным для запуска проекта вживую, прежде чем вкладывать в него слишком много.

Ответ 1

Программы

Go могут прослушивать порт 80 и напрямую обращаться к HTTP-запросам. Вместо этого вы можете использовать обратный прокси-сервер перед вашей программой Go, чтобы он прослушивал порт 80 и подключался к вашей программе на порту, скажем, 4000. Есть много причин для этого: не нужно запускать ваша программа Go как root, обслуживающая другие веб-сайты/службы на одном и том же хосте, завершение SSL, балансировку нагрузки, ведение журнала и т.д.

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

HAProxy очень легко настроить, если вы прочитали его документацию (HTML-версия). Весь мой файл haproxy.cfg для одного из моих проектов Go следует, если вам нужен стартовый pont.

global
        log     127.0.0.1       local0
        maxconn 10000
        user    haproxy
        group   haproxy
        daemon

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        timeout connect 5000
        timeout client  50000
        timeout server  50000

frontend http
        bind :80
        acl  is_stats  hdr(host)       -i      hastats.myapp.com
        use_backend    stats   if      is_stats
        default_backend        myapp
        capture        request header Host     len     20
        capture        request header Referer  len     50

backend myapp
        server  main    127.0.0.1:4000

backend stats
       mode     http
       stats    enable
       stats    scope   http
       stats    scope   myapp
       stats    realm   Haproxy\ Statistics
       stats    uri     /
       stats    auth    username:password

Nginx еще проще.

Что касается управления сервисами, я запускаю свою программу Go в качестве системной службы. Я думаю, что все это делают. Мой сервер запускает Ubuntu, поэтому он использует Upstart. Я поставил это на /etc/init/myapp.conf для Upstart для управления моей программой:

start on runlevel [2345]
stop on runlevel [!2345]

chdir /home/myapp/myapp
setgid myapp
setuid myapp
exec ./myapp start 1>>_logs/stdout.log 2>>_logs/stderr.log

Другим аспектом является развертывание. Один из вариантов - развернуть, просто отправив двоичный файл программы и необходимые активы. Это довольно большое решение IMO. Я использую другой вариант: компиляция на сервере. (Я перейду к развертыванию с двоичными файлами, когда я установил так называемую систему "Непрерывная интеграция/развертывание".)

У меня на сервере небольшая оболочка script, которая извлекает код для моего проекта из удаленного репозитория Git, строит его с помощью Go, копирует двоичные файлы и другие активы в ~/myapp/ и перезапускает службу.

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

Ответ 2

nginx для:

  • Обратный HTTP-прокси для моего приложения Go
  • Обработка статических файлов
  • Отключение SSL
  • Заголовки HTTP (Cache-Control, et al.)
  • Журналы доступа (и, следовательно, использование вращения системного журнала)
  • Переписывает (голый на www, http://на https://и т.д.)

nginx делает это очень просто, и хотя вы можете напрямую работать с Go благодаря net/http, там много "повторного изобретательства колеса", и такие вещи, как глобальные HTTP-заголовки, связаны с некоторыми шаблонами, которые вы, вероятно, можете избежать.

supervisord для управления моим двоичным кодом Go. Ubuntu Upstart (как упоминается Mostafa) также хорош, но мне нравится супервизор, поскольку он относительно дистрибутивен и хорошо документирован.

Супервизор, для меня:

  • Запускает двоичный файл Go при необходимости
  • Возвращает его после сбоя
  • Сохраняет мои переменные среды (ключи сеанса авторизации и т.д.) как часть одной конфигурации.
  • Запускает мою БД (чтобы убедиться, что мой двоичный файл Go не работает без него)

Ответ 3

Вы можете привязать свой двоичный файл к сокету к привилегированным портам домена Интернета (номера портов меньше 1024) с помощью setcap

setcap 'cap_net_bind_service=+ep' /path/to/binary

  • Эту команду необходимо обойти. sudo при необходимости
  • Каждая новая версия вашей программы приведет к созданию нового двоичного файла, который должен быть перезапущен с помощью setcap

setcap документация

cap_net_bind_service документация

Ответ 4

Для тех, кто хочет, чтобы приложение простого go работало как демон, используйте systemd (поддерживается многими дистрибутивами linux) вместо Upstart.

Создайте файл службы в

touch /etc/systemd/system/my-go-daemon.service

Enter

[Unit]
Description=My Go App

[Service]
Type=simple
WorkingDirectory=/my/go/app/directory
ExecStart=/usr/lib/go run main.go 

[Install]
WantedBy=multi-user.target

Затем включите и запустите сервис

systemctl enable my-go-daemon
systemctl start my-go-daemon
systemctl status my-go-daemon

systemd имеет отдельную систему ведения журнала, которая позволит вам вести журналы для легкой съемки.