healthcheck一个不错的 Kubernetes liveness && readiness prob handler 实现
healthcheck 实现了一个开箱即用的Kubernetes liveness&& readiness prob 实现,我们可以直接拿来使用
已经包含了tcp,dns,http,Goroutine prob,同时也支持prometheus,还是很方便的
以下是一个简单的试用
参考代码
package main
import (
"fmt"
"log"
"net/http"
"net/http/httptest"
"net/http/httputil"
"os"
"os/signal"
"strings"
"syscall"
"time"
"github.com/heptiolabs/healthcheck"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
func main() {
registry := prometheus.NewRegistry()
// Create a metrics-exposing Handler for the Prometheus registry
// The healthcheck related metrics will be prefixed with the provided namespace
health := healthcheck.NewMetricsHandler(registry, "example")
// Create a Handler that we can use to register liveness and readiness checks.
// Make sure we can connect to an upstream dependency over TCP in less than
// 50ms. Run this check asynchronously in the background every 10 seconds
// instead of every time the /ready or /live endpoints are hit.
//
// Async is useful whenever a check is expensive (especially if it causes
// load on upstream services).
// upstreamAddr := "upstream.example.com:5432"
// health.AddReadinessCheck(
// "upstream-dep-tcp",
// healthcheck.Async(healthcheck.TCPDialCheck(upstreamAddr, 50*time.Millisecond), 10*time.Second))
// Add a readiness check against the health of an upstream HTTP dependency
upstreamURL := "https://www.cnblogs.com/rongfengliang"
health.AddReadinessCheck(
"upstream-dep-http",
healthcheck.HTTPGetCheck(upstreamURL, 500*time.Millisecond))
// Implement a custom check with a 50 millisecond timeout.
health.AddLivenessCheck("custom-check-with-timeout", healthcheck.Timeout(func() error {
// Simulate some work that could take a long time
time.Sleep(time.Millisecond * 100)
return nil
}, 500*time.Millisecond))
// Expose the readiness endpoints on a custom path /healthz mixed into
// our main application mux.
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, world!"))
})
mux.HandleFunc("/healthz", health.LiveEndpoint)
mux.Handle("/metrics", promhttp.HandlerFor(registry, promhttp.HandlerOpts{}))
// Sleep for just a moment to make sure our Async handler had a chance to run
//time.Sleep(500 * time.Millisecond)
go http.ListenAndServe("0.0.0.0:9402", mux)
// Make a sample request to the /healthz endpoint and print the response.
fmt.Println(dumpRequest(mux, "GET", "/healthz"))
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
sig := <-sigChan
log.Printf("shutting down %v signal received", sig)
}
func dumpRequest(handler http.Handler, method string, path string) string {
req, err := http.NewRequest(method, path, nil)
if err != nil {
panic(err)
}
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
dump, err := httputil.DumpResponse(rr.Result(), true)
if err != nil {
panic(err)
}
return strings.Replace(string(dump), "\r\n", "\n", -1)
}
参考效果
参考资料
https://github.com/heptiolabs/healthcheck
https://godoc.org/github.com/heptiolabs/healthcheck#Handler