wlf f051014ac2 提交正常运行的所有代码 | 1 year ago | |
---|---|---|
.. | ||
.travis.yml | 1 year ago | |
LICENSE | 1 year ago | |
README.md | 1 year ago | |
graceful.go | 1 year ago | |
keepalive_listener.go | 1 year ago | |
limit_listen.go | 1 year ago |
Graceful is a Go 1.3+ package enabling graceful shutdown of http.Handler servers.
To install, simply execute:
go get gopkg.in/tylerb/graceful.v1
I am using gopkg.in to control releases.
Using Graceful is easy. Simply create your http.Handler and pass it to the Run
function:
package main
import (
"gopkg.in/tylerb/graceful.v1"
"net/http"
"fmt"
"time"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "Welcome to the home page!")
})
graceful.Run(":3001",10*time.Second,mux)
}
Another example, using Negroni, functions in much the same manner:
package main
import (
"github.com/codegangsta/negroni"
"gopkg.in/tylerb/graceful.v1"
"net/http"
"fmt"
"time"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "Welcome to the home page!")
})
n := negroni.Classic()
n.UseHandler(mux)
//n.Run(":3000")
graceful.Run(":3001",10*time.Second,n)
}
In addition to Run there are the http.Server counterparts ListenAndServe, ListenAndServeTLS and Serve, which allow you to configure HTTPS, custom timeouts and error handling. Graceful may also be used by instantiating its Server type directly, which embeds an http.Server:
mux := // ...
srv := &graceful.Server{
Timeout: 10 * time.Second,
Server: &http.Server{
Addr: ":1234",
Handler: mux,
},
}
srv.ListenAndServe()
This form allows you to set the ConnState callback, which works in the same way as in http.Server:
mux := // ...
srv := &graceful.Server{
Timeout: 10 * time.Second,
ConnState: func(conn net.Conn, state http.ConnState) {
// conn has a new state
},
Server: &http.Server{
Addr: ":1234",
Handler: mux,
},
}
srv.ListenAndServe()
When Graceful is sent a SIGINT or SIGTERM (possibly from ^C or a kill command), it:
timeout
duration to give active requests a chance to finish.stopChan
, waking up any blocking goroutines.If the timeout
argument to Run
is 0, the server never times out, allowing all active requests to complete.
If you wish to stop the server in some way other than an OS signal, you may call the Stop()
function.
This function stops the server, gracefully, using the new timeout value you provide. The StopChan()
function
returns a channel on which you can block while waiting for the server to stop. This channel will be closed when
the server is stopped, allowing your execution to proceed. Multiple goroutines can block on this channel at the
same time and all will be signalled when stopping is complete.
timeout
to 0:If you set the timeout
to 0
, it waits for all connections to the server to disconnect before shutting down.
This means that even though requests over a connection have finished, it is possible for the client to hold the
connection open and block the server from shutting down indefinitely.
This is especially evident when graceful is used to run HTTP/2 servers. Clients like Chrome and Firefox have been observed to hold onto the open connection indefinitely over HTTP/2, preventing the server from shutting down. In addition, there is also the risk of malicious clients holding and keeping the connection alive.
It is understandable that sometimes, you might want to wait for the client indefinitely because they might be uploading large files. In these type of cases, it is recommended that you set a reasonable timeout to kill the connection, and have the client perform resumable uploads. For example, the client can divide the file into chunks and reupload chunks that were in transit when the connection was terminated.
If you would like to contribute, please:
All pull requests should:
go fmt
formatted.