Конфігурація веб-додатків Golang


120

Для тих із вас, хто працює з виробництвом "Гокенд":

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

Я мало бачив цієї теми, окрім людей, які використовують стандартний пакет бібліотеки net / http для підтримки роботи сервера. Я читаю, використовуючи Nginx для передачі запитів на сервер Go - nginx за допомогою Go

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

Чи є більш солідний режим виробництва?

Окрім мого наміру - я планую підключити сервер REST, що працює на наступному проекті, для мого наступного проекту і хочу переконатися, що Go стане життєздатним для запуску проекту в прямому ефірі, перш ніж я занадто багато вкладу в нього.


3
"сервер не автоматично перезапуститься, якщо машину перезапустили (без додаткових скриптів конфігурації)." Я не думаю, що це можна зробити. В ідеалі ви створили б сценарії init / systemd / upstart для послуги. Це рекомендований спосіб контролю будь-якого демона Unix.
Intermernet

Право ти є. Я думаю, я мав на увазі це на відміну від такого сервера, як apache, який автоматично встановлює ці функції під час встановлення.
Чейзф

Відповіді:


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

Що ви робите з обертанням журналу? Це майже єдина причина, чому я використовую нагляд, але він страждає, коли ведеться занадто багато журналу.
fiorix

@fiorix, я впевнений, що ви можете відкрити інше питання щодо обертання журналу, але все ж якщо ви перебуваєте на 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 (кеш-контроль та ін.)
  • Журнали доступу (і, отже, використання обертання системного журналу)
  • Переписує (голий до www, http: // до https: // тощо)

nginx робить це дуже просто, і, хоча ви можете обслуговувати безпосередньо з Go завдяки net/http, існує багато "переосмислення колеса", і такі речі, як глобальні заголовки HTTP, передбачають певну котельну плиту, якої ви, ймовірно, можете уникнути.

нагляд за керуванням моїм бінарним Go. Ubuntu Upstart (як згадував Mostafa) також хороший, але мені подобається нагляд, оскільки він відносно дистриб'юторський і добре документований.

Контроль, для мене:

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

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 має окрему систему обліку журналів, яка дозволить вам проводити журнали хвостів для легкого усунення неполадок.


5

Ви можете прив’язати свій двійковий файл до сокета до привілейованих портів Інтернет-домену (номера портів менше 1024), використовуючи setcap

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

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

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.