recommendation - Configuración de la aplicación web de producción Golang
title seo length (4)
Para aquellos de ustedes que ejecutan Go backends en producción:
¿Cuál es tu stack / configuración para ejecutar una aplicación web Go?
No he visto mucho sobre este tema, además de las personas que usan el paquete net / http de biblioteca estándar para mantener un servidor en funcionamiento. Leí usando Nginx para pasar solicitudes a un servidor Go - nginx con Go
Esto me parece un poco frágil. Por ejemplo, el servidor no se reiniciará automáticamente si la máquina se reinicia (sin scripts de configuración adicionales).
¿Hay una configuración de producción más sólida?
Aparte de mi intención, estoy planificando un servidor backend Go powered para mi próximo proyecto y quiero asegurarme de que Go será viable para lanzar el proyecto en vivo antes de invertir demasiado en él.
Los programas Go pueden escuchar en el puerto 80 y atender solicitudes HTTP directamente. En su lugar, es posible que desee utilizar un proxy inverso delante de su programa Go, para que escuche en el puerto 80 y se conecte a su programa en el puerto, digamos, 4000. Hay muchas razones para hacer esto último: no tener que ejecutar su programa Go como root, sirviendo a otros sitios web / servicios en el mismo host, terminación SSL, balanceo de carga, registro, etc.
Yo uso HAProxy en el frente. Cualquier proxy inverso podría funcionar. Nginx también es una gran opción (mucho más popular que HAProxy y capaz de hacer más).
HAProxy es muy fácil de configurar si lee su documentation ( versión HTML ). Mi archivo haproxy.cfg
completo para uno de mis proyectos de Go sigue, en caso de que necesite un pont inicial.
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 es aún más fácil.
En cuanto al control del servicio, ejecuto mi programa Go como un servicio del sistema. Creo que todos hacen eso. Mi servidor ejecuta Ubuntu, por lo que usa Upstart. He puesto esto en /etc/init/myapp.conf
para que Upstart controle mi programa:
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
Otro aspecto es la implementación. Una opción es implementar solo enviando el archivo binario del programa y los activos necesarios. Esta es una gran solución IMO. Uso la otra opción: compilar en el servidor. (Pasaré a implementar con archivos binarios cuando configuro un sistema denominado "Integración / Despliegue continuo").
Tengo un pequeño script de shell en el servidor que extrae código para mi proyecto de un repositorio remoto de Git, lo crea con Go, copia los binarios y otros activos a ~/myapp/
y reinicia el servicio.
En general, todo el asunto no es muy diferente de cualquier otra configuración de servidor: debe tener una forma de ejecutar su código y hacer que sirva solicitudes HTTP. En la práctica, Go ha demostrado ser muy estable para esto.
Para aquellos que quieren una aplicación simple para ejecutar como daemon, use systemd (Compatible con muchas distros de Linux) en lugar de Upstart.
Crea un archivo de servicio en
touch /etc/systemd/system/my-go-daemon.service
Entrar
[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
Luego habilite e inicie el servicio
systemctl enable my-go-daemon
systemctl start my-go-daemon
systemctl status my-go-daemon
systemd tiene un sistema de diario por separado que le permitirá rastrear registros para facilitar la resolución de problemas.
Puede vincular su binario a un socket con puertos privilegiados de dominio de Internet (números de puerto inferiores a 1024) usando setcap
setcap ''cap_net_bind_service=+ep'' /path/to/binary
- Este comando necesita ser escalado.
sudo
según sea necesario - Cada nueva versión de su programa dará como resultado un nuevo binario que necesitará ser reautorizado por
setcap
nginx para:
- Invierta el proxy HTTP a mi aplicación Go
- Manejo de archivos estáticos
- Terminación SSL
- Encabezados HTTP (Cache-Control, et al.)
- Registros de acceso (y por lo tanto aprovechar la rotación del registro del sistema)
- Reescribe (desnudo a www, http: // a https: //, etc.)
nginx hace que esto sea muy fácil, y aunque puede servir directamente desde Go gracias a net/http
, hay una gran cantidad de "reinventar la rueda" y cosas como encabezados HTTP globales implican algunos repetitivos que probablemente pueda evitar.
supervisord para administrar mi Go binary. Upstart de Ubuntu (como lo menciona Mostafa) también es bueno, pero me gusta Supervisar, ya que es relativamente distrótico y está bien documentado.
Supervisord, para mí:
- Ejecuta mi binario Go según sea necesario
- Lo trae después de un accidente
- Mantiene mis variables ambientales (claves de autenticación de sesión, etc.) como parte de una única configuración.
- Ejecuta mi base de datos (para asegurarme de que mi binario Go no se está ejecutando sin él)