Inspired by overseer and endless, with minimum codes and handy api to make http server graceful.
- golang 1.8+
- linux/darwin(windows not supported)
- Graceful reload http servers, zero downtime on upgrade.
- Compatible with systemd, supervisor, etc.
- Drop-in placement for
http.ListenAndServe
type handler struct {
}
func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, port: %v, %q", r.Host, html.EscapeString(r.URL.Path))
}
func main(){
graceful.ListenAndServe(":9222", &handler{})
}
multi servers:
func main(){
server := graceful.NewServer()
server.Register("0.0.0.0:9223", &handler{})
server.Register("0.0.0.0:9224", &handler{})
server.Register("0.0.0.0:9225", &handler{})
err := server.Run()
fmt.Printf("error: %v\n", err)
}
More example checkout example folder.
SIGHUP
and SIGUSR1
on master proccess are used as default to reload server. server.Reload()
func works as well from your code.
graceful
starts a master process to keep pid unchaged for process managers(systemd, supervisor, etc.), and a worker proccess listen to actual addrs. That means graceful
starts one more process. Fortunately, master proccess waits for signals and reload worker when neccessary, which is costless since reload is usually low-frequency action.
StopTimeout
. Unfinished old connections will be drop in{StopTimeout}
seconds, default 20s, after new server is up.
server := graceful.NewServer(graceful.WithStopTimeout(time.Duration(4 * time.Hour)))
server.Register(addr, handler)
if err := server.Run(); err != nil {
log.Fatal(err)
}
Signals
. Default reload signals:syscall.SIGHUP, syscall.SIGUSR1
and stop signals:syscall.SIGKILL, syscall.SIGTERM, syscall.SIGINT
could be overwrited with:
server := graceful.NewServer(graceful.WithStopSignals([]syscall.Signal{syscall.SIGKILL}), graceful.WithReloadSignals([]syscall.Signal{syscall.SIGHUP}))
server.Register(addr, handler)
if err := server.Run(); err != nil {
log.Fatal(err)
}
- ListenAndServeTLS
- Add alternative api: Run in single process without master-worker