Atualmente, tenho o seguinte servidor HTTP escrito em Go:
func main() {
http.HandleFunc("/", func(response http.ResponseWriter, request *http.Request) {
http.ServeFile(response, request, "/var/www/default/htdocs/index.html")
})
http.Handle("/public/", http.StripPrefix("/public/", http.FileServer(http.Dir("/var/www/default/htdocs/public"))))
http.HandleFunc("/json", func(response http.ResponseWriter, request *http.Request) {
// serves a JSON response
})
http.HandleFunc("/socket", func(w http.ResponseWriter, r *http.Request) {
// replies to the WebSocket
})
http.ListenAndServe(":3000", nil)
}
Eu vi alguns benchmarks que mostram que o nginx pode servir muito mais pedidos por segundo quando se trata de arquivos estáticos. Outro recurso útil do nginx é que ele pode compactar as respostas de forma transparente e até mesmo servir arquivos pré-compactados com o módulo gzip_static
.
Idealmente, quero que o nginx atenda todos os arquivos (estáticos) existentes e faça proxy de tudo o que não existe para o Go:
location / {
try_files $uri $uri/ @go;
}
location @go {
proxy_pass http://127.0.0.1:3000/;
proxy_set_header Host $host;
}
Infelizmente, o nginx não gosta da configuração acima:
nginx: [emerg] "proxy_pass" cannot have URI part in location given by
regular expression, or inside named location, or inside "if"
statement, or inside "limit_except" block in
/etc/nginx/sites-enabled/default:23
Neste ponto, sei que tenho várias opções:
1) coloque proxy_pass
no bloco location /
Mas isso fará proxy em tudo, até mesmo nos arquivos existentes (estáticos).
2) escreva blocos de localização /json
e /socket
individuais em nginx
Mas se eu quiser adicionar mais manipuladores no Go, eu também tenho que atualizar o vnet nginx adequadamente.
3) reescreva o código Go e use fastcgi_pass
em nginx em vez de proxy_pass
location @go {
fastcgi_pass 127.0.0.1:9000;
}
Eu também teria que alterar o código Go para usar net/http/fcgi
em vez de net/http
, o problema com isso é que eu não sei como especificar os caminhos ( /json
ou /socket
) com < href="http://golang.org/src/pkg/net/http/fcgi/child.go?s=6606:6660#L262"> fcgi.Serve()
.
Além disso, o FastCGI parece ser 4 vezes mais lento que o HTTP: link .
4) descartar totalmente o nginx
Faça o Go servir tudo (incluindo arquivos estáticos) e manipule a compactação gzip em todas as solicitações.
Como posso fazer o nginx e o Go para se comportar como eu quero (de preferência com a interface HTTP)?
Desculpas se esta pergunta for demasiado básica, esta é a minha primeira experiência a escrever uma aplicação Web Go.
Pergunta adicional
No PHP, eu aponto fastcgi_pass
para o soquete php-fpm
Unix. Se qualquer solicitação tiver um erro fatal do PHP , as próximas solicitações ainda serão exibidas. No entanto, se meu Go code chamar panic()
, o programa será encerrado e o serviço parará de responder. Qual é a melhor maneira de lidar com isso no Go?