2013-07-03 21 views
109

Per quelli di voi che eseguono Go backend in produzione:Configurazione dell'applicazione web di produzione Golang

Qual è lo stack/configurazione per l'esecuzione di un'applicazione Web Go?

Non ho visto molto su questo argomento a parte le persone che utilizzano il pacchetto net/http della libreria standard per mantenere attivo un server. Ho letto utilizzando Nginx per passare richieste a un server Go - nginx with Go

Mi sembra un po 'fragile. Ad esempio, il server non si riavvierà automaticamente se la macchina è stata riavviata (senza ulteriori script di configurazione).

Esiste una configurazione di produzione più solida?

A parte le mie intenzioni - sto pianificando un server di backend REST Go powered per il mio prossimo progetto e voglio assicurarmi che Go sia praticabile per l'avvio del progetto dal vivo prima di investire troppo in esso.

+1

"il server non si riavvierà automaticamente se la macchina è stata riavviata (senza script di configurazione aggiuntivi)." Non penso che questo possa essere fatto. Idealmente avresti creato script init/systemd/upstart per il servizio. Questo è il modo consigliato per controllare qualsiasi demone unix. – Intermernet

+0

Proprio come te. Immagino di volerlo dire in contrasto con un server come Apache, che imposta automaticamente queste funzionalità al momento dell'installazione. – Chaseph

risposta

127

I programmi Go possono ascoltare sulla porta 80 e servire direttamente le richieste HTTP. Invece, potresti voler utilizzare un proxy inverso di fronte al tuo programma Go, in modo che sia in ascolto sulla porta 80 e si connetta al tuo programma sulla porta, ad esempio 4000. Ci sono molte ragioni per farlo: non dover eseguire il tuo programma Go come root, che serve altri siti/servizi sullo stesso host, terminazione SSL, bilanciamento del carico, registrazione, ecc.

Io uso HAProxy di fronte. Qualsiasi proxy inverso potrebbe funzionare. Nginx è anche un'ottima opzione (molto più popolare di HAProxy e capace di fare di più).

HAProxy è molto facile da configurare se si legge il suo documentation (HTML version). Il mio intero file haproxy.cfg per uno dei miei progetti Go segue, nel caso in cui sia necessario un pont di partenza.

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 è ancora più semplice.

Per quanto riguarda il controllo del servizio, eseguo il mio programma Go come servizio di sistema. Penso che tutti lo facciano. Il mio server esegue Ubuntu, quindi usa Upstart. Ho messo questo a /etc/init/myapp.conf per Upstart per controllare il mio programma:

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 

Un altro aspetto è la distribuzione. Un'opzione è quella di distribuire semplicemente inviando il file binario del programma e le risorse necessarie. Questa è una soluzione piuttosto grande IMO. Io uso l'altra opzione: compilazione sul server. (Passerò alla distribuzione con file binari quando creerò un cosiddetto sistema "Integrazione/Distribuzione continua")

Ho un piccolo script di shell sul server che estrae il codice per il mio progetto da un Git remoto repository, lo crea con Go, copia i file binari e altre risorse su ~/myapp/ e riavvia il servizio.

Nel complesso, il tutto non è molto diverso da qualsiasi altra configurazione del server: è necessario disporre di un modo per eseguire il codice e farlo servire richieste HTTP. In pratica, Go ha dimostrato di essere molto stabile per questa roba.

+7

Ottima risposta! Buoni esempi di tutto il necessario per una configurazione di base consigliata. – Intermernet

+0

Cosa fai per la rotazione dei log? Questo è praticamente l'unico motivo per cui uso supervisord ma soffre quando c'è troppa registrazione in corso. – fiorix

+0

@fiorix, sono abbastanza sicuro che potresti aprire una domanda SO diversa sulla rotazione dei log, ma se sei su unix e vuoi usare gli strumenti standard, controlla logrotate: http://linuxcommand.org/man_pages/logrotate8. html. Questo è usato da molti dei servizi più noti (apache, yum, ecc.) Ed è abbastanza facile da configurare. –

56

nginx per:

  • proxy HTTP inverso alla mia domanda Go
  • movimentazione File statico
  • terminazione SSL
  • intestazioni HTTP (Cache-Control, et al.)
  • log di accesso (e quindi facendo leva sulla rotazione del registro di sistema)
  • Riscrive (nuda su www, http: // a https: //, ecc.)

nginx rende questo molto facile, e anche se si può servire direttamente da Go grazie a net/http, c'è un sacco di "re-inventare la ruota" e cose del genere intestazioni HTTP globali comporta qualche boilerplate probabilmente si può evitare.

supervisord per la gestione del mio file binario. Anche l'Upstart di Ubuntu (come menzionato da Mostafa) è buono, ma mi piace il supervisore perché è relativamente distro-agnostico ed è ben documentato.

Supervisord, per me:

  • Esegue il mio binario Go come necessario
  • lo porta dopo un crash
  • mi tiene variabili ambientali (sessione chiavi auth, etc.) come parte di un unico config.
  • Runs mia DB (per assicurarsi che il mio binario Go non è in esecuzione senza di esso)
4

È possibile vincolare il proprio binario ad una presa a dominio Internet porte privilegiate (numeri di porta inferiori a 1024) utilizzando setcap

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

  1. Questo comando deve essere intensificato. sudo se necessario
  2. Ogni nuova versione del programma si tradurrà in un nuovo binario che dovrà essere reauthorized da setcap

setcap documentation

cap_net_bind_service documentation

2

Per coloro che vogliono semplice go applicazione in esecuzione come demone, utilizzare systemd (supportato da molte distribuzioni di Linux) invece di Upstart.

Creare un file di servizio a

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

Inserisci

[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 

Poi attivare e avviare il servizio

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

systemd ha un sistema di journaling separato che vi permetterà di log di coda per facile risoluzione dei problemi.

Problemi correlati