An open API service indexing awesome lists of open source software.

https://github.com/kuangchanglang/graceful

graceful reload golang http server, zero downtime, compatible with systemd, supervisor
https://github.com/kuangchanglang/graceful

golang graceful-restart-process supervisor systemd

Last synced: 5 months ago
JSON representation

graceful reload golang http server, zero downtime, compatible with systemd, supervisor

Awesome Lists containing this project

README

          

# graceful
Inspired by [overseer](https://github.com/jpillora/overseer) and [endless](https://github.com/fvbock/endless), with minimum codes and handy api to make http server graceful.

# Prerequisite
- golang 1.8+
- linux/darwin(windows not supported)

# Feature
- Graceful reload http servers, zero downtime on upgrade.
- Compatible with systemd, supervisor, etc.
- Drop-in placement for ```http.ListenAndServe```

# Example
``` go
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:
```go
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.

# Reload
```SIGHUP``` and ```SIGUSR1``` on master proccess are used as default to reload server. ```server.Reload()``` func works as well from your code.

# Drawbacks
```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.

# Default values
* ```StopTimeout```. Unfinished old connections will be drop in ```{StopTimeout}``` seconds, default 20s, after new server is up.
```go
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:
```go
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)
}
```

# TODO
- ListenAndServeTLS
- Add alternative api: Run in single process without master-worker