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

120

Для тех из вас, кто использует бэкенды Go в производственной среде:

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

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

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

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

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

Chaseph
источник
3
«сервер не перезапустился бы автоматически, если бы машина была перезапущена (без дополнительных сценариев конфигурации)». Я не думаю, что это можно сделать. В идеале вы должны создать сценарии init / systemd / upstart для службы. Это рекомендуемый способ управления любым демоном unix.
Intermernet
Вы правы. Думаю, я имел в виду это в отличие от сервера, такого как apache, который автоматически настраивает эти функции во время установки.
Chaseph

Ответы:

134

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

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

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

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

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

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

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

Мостафа
источник
9
Отличный ответ! Хорошие примеры всего необходимого для рекомендуемой базовой настройки.
Intermernet
Что вы делаете с ротацией журналов? Это практически единственная причина, по которой я использую supervisord, но он страдает, когда ведется слишком много журналов.
fiorix
@fiorix, я почти уверен, что вы могли бы открыть другой вопрос SO о ротации журналов, но все же, если вы используете unix и хотите использовать стандартные инструменты, проверьте logrotate: linuxcommand.org/man_pages/logrotate8.html . Он используется многими хорошо известными службами (apache, yum и т. Д.) И довольно легко настраивается.
Doody P
Насколько легко было бы создать собственный обратный прокси в Go? Будет ли это значительно хуже, чем использование nginx или haproxy? Я имею в виду, что Go имеет отличную поддержку HTTP / HTTPS / HTTP / 2.
thomasrutter
58

nginx для:

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

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

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

Супервайзер, для меня:

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

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

Создайте служебный файл по адресу

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

Войти

[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 имеет отдельную систему журналирования, которая позволит вам отслеживать журналы для облегчения поиска и устранения неисправностей.

mixdev
источник
5

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

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

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

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

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

Emperor_Earth
источник