plugin/health: make reload work (#1585)

* plugin/health: make reload work

Remove the once.Do from the startup, so we can re-bind the HTTP
listener. Also clarify the usage of health in multiple server blocks
(this is not the best approach - but there isn't a generic solution at
this point).

Manual tested as we lack testing infra, i.e kill -SIGUSR1 and some
CURLing of the health endpoint.

* Readme test fix

* update

* dont need this
This commit is contained in:
Miek Gieben 2018-03-02 21:40:14 -08:00 committed by GitHub
parent acf823cd78
commit 804f745951
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 32 deletions

View file

@ -8,8 +8,7 @@
By enabling *health* any plugin that implements
[healt.Healther interface](https://godoc.org/github.com/coredns/coredns/plugin/health#Healther)
will be queried for it's health. The combined
health is exported, by default, on port 8080/health .
will be queried for it's health. The combined health is exported, by default, on port 8080/health .
## Syntax
@ -20,8 +19,8 @@ health [ADDRESS]
Optionally takes an address; the default is `:8080`. The health path is fixed to `/health`. The
health endpoint returns a 200 response code and the word "OK" when CoreDNS is healthy. It returns
a 503. *health* periodically (1s) polls plugin that exports health information. If any of the
plugin signals that it is unhealthy, the server will go unhealthy too. Each plugin that
supports health checks has a section "Health" in their README.
plugin signals that it is unhealthy, the server will go unhealthy too. Each plugin that supports
health checks has a section "Health" in their README.
More options can be set with this extended syntax:
@ -34,6 +33,21 @@ health [ADDRESS] {
* Where `lameduck` will make the process unhealthy then *wait* for **DURATION** before the process
shuts down.
If you have multiple Server Block and need to export health for each of the plugins, you must run
health endpoints on different ports:
~~~ corefile
com {
whoami
health :8080
}
net {
erratic
health :8081
}
~~~
## Plugins
Any plugin that implements the Healther interface will be used to report health.
@ -60,7 +74,7 @@ Set a lameduck duration of 1 second:
~~~ corefile
. {
health localhost:8091 {
health localhost:8092 {
lameduck 1s
}
}

View file

@ -10,8 +10,6 @@ import (
"time"
)
var once sync.Once
// Health implements healthchecks by polling plugins.
type health struct {
Addr string
@ -39,33 +37,26 @@ func (h *health) OnStartup() error {
h.Addr = defAddr
}
once.Do(func() {
ln, err := net.Listen("tcp", h.Addr)
if err != nil {
log.Printf("[ERROR] Failed to start health handler: %s", err)
ln, err := net.Listen("tcp", h.Addr)
if err != nil {
return err
}
h.ln = ln
h.mux = http.NewServeMux()
h.mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
if h.Ok() {
w.WriteHeader(http.StatusOK)
io.WriteString(w, ok)
return
}
h.ln = ln
h.mux = http.NewServeMux()
h.mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
if h.Ok() {
w.WriteHeader(http.StatusOK)
io.WriteString(w, ok)
return
}
w.WriteHeader(http.StatusServiceUnavailable)
})
go func() {
http.Serve(h.ln, h.mux)
}()
go func() {
h.overloaded()
}()
w.WriteHeader(http.StatusServiceUnavailable)
})
go func() { http.Serve(h.ln, h.mux) }()
go func() { h.overloaded() }()
return nil
}

View file

@ -68,7 +68,7 @@ func setup(c *caddy.Controller) error {
})
c.OnStartup(h.OnStartup)
c.OnFinalShutdown(h.OnShutdown)
c.OnShutdown(h.OnShutdown)
// Don't do AddPlugin, as health is not *really* a plugin just a separate webserver running.
return nil