Как это работает, чтобы понимали. Я опишу истинно
правильный путь, но долгий: (как подсказал
pygame , по бенчмаркам
https://gist.github.com/hgfischer/7965620 всё же нативный хттп сервер в Go быстрее, чем nginx с fcgi, т.к. у Go гавняная реализация fcgi, поэтому вместо fcgi быстрее будет обычный http proxy_pass).
1) Ставится веб-сервер нормальный, а не тот, который есть в самом Go. То есть, ставим nginx. Настраиваем ему все url маршруты, настраиваем отдачу статики.
2) За динамикой nginx будет обращаться к нашему Go демону. По протоколу fast-cgi. Именно по нему, потому что nginx его умеет и вообще он хорош (upd: но не в Go). Это короч бинарный протокол по которому nginx передаёт в нашу Go программу HTTP заголовки запроса от браузера и получает обратно HTTP ответ. Для этого ставим простейшую обёртку для fast-cgi под названием spawn-fcgi, она будет преднастраивать и запускать нашу Go программу, готовую для общения по протоколу fast-cgi.
3) На случай, если наша Go программа падает. Либо уже у нас есть система, которая следит за демонами и поднимает их в случае падения (systemd, upstart), тогда конфигурируем её, либо ставим таковую и тоже конфигурируем.
Привожу пример как это всё сделано у меня (самый популярный стек технологий) на Debian:
1) nginx
server {
server_name otboi.****;
listen 80;
include fastcgi_params;
...
location / {
fastcgi_pass unix:/var/run/otboinik.sock;
}
2) systemd конфиг, который стартует нашу Go программу, завёрнутую в spawn-fcgi
[Unit]
Description=Otboinik
[Service]
Restart=always
Environment=OTBOINIK_BIN=/opt/гыы/otboinik/bin/otboinik
Environment=OTBOINIK_PID=/var/run/otboinik.pid
Environment=OTBOINIK_USER=гыыыы
Environment=OTBOINIK_SOCKET=/var/run/otboinik.sock
Environment=OTBOINIK_SOCKET_USER=гыыыыы
Environment=OTBOINIK_SOCKET_MODE=0666
ExecStart=/usr/bin/spawn-fcgi -s $OTBOINIK_SOCKET -M $OTBOINIK_SOCKET_MODE -n -P $OTBOINIK_PID -u $OTBOINIK_USER -U $OTBOINIK_SOCKET_USER -G $OTBOINIK_SOCKET_USER $OTBOINIK_BIN
[Install]
WantedBy=multi-user.target
3) Сам Go код
import (
"net/http"
"net/http/fcgi"
)
type Server struct {
}
func (s Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// чиста пример
jsonblob := r.FormValue("events")
if jsonblob == "" {
w.WriteHeader(http.StatusNotAcceptable)
return
}
}
func main() {
server := Server{}
func() {
fcgi.Serve(nil, server)
}()
waitchan := make(chan int, 1)
<-waitchan
}