Go
Health check
Learn to write a /healthz health endpoint.
Health checks
Orchestrators ask two questions: liveness — is the process alive? (restart it if not) and readiness — is it ready for traffic? (is the database connected, is warm-up done?).
mux.HandleFunc("GET /livez", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
})
mux.HandleFunc("GET /readyz", func(w http.ResponseWriter, r *http.Request) {
if err := db.PingContext(r.Context()); err != nil {
http.Error(w, "db yok", http.StatusServiceUnavailable)
return
}
w.Write([]byte("ok"))
})
Not ready while shutting down
During graceful shutdown the service first flips readiness to "not ready", waits for the load balancer to stop sending traffic, then finishes in-flight requests and exits. An atomic flag is enough for this:
var hazir atomic.Bool
hazir.Store(true)
// on SIGTERM
hazir.Store(false)
time.Sleep(5 * time.Second)
srv.Shutdown(ctx)
Exercise Readiness endpoint
Declare var hazir atomic.Bool. The /readyz handler returns 503 if the flag is false and 200 if true. Send two requests — with the flag false and after setting it true — and print both codes on one line.
Show example solution
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"sync/atomic"
)
var hazir atomic.Bool
func readyz(w http.ResponseWriter, r *http.Request) {
if !hazir.Load() {
http.Error(w, "hazır değil", http.StatusServiceUnavailable)
return
}
w.Write([]byte("ok"))
}
func istek() int {
rec := httptest.NewRecorder()
readyz(rec, httptest.NewRequest("GET", "/readyz", nil))
return rec.Code
}
func main() {
once := istek()
hazir.Store(true)
fmt.Println(once, istek())
}
Test yourself
-
What can happen if the liveness check also checks the database?
- The application speeds up
- A brief database outage restarts every pod for nothing
- It becomes safer
- Nothing changes
Show answer
A brief database outage restarts every pod for nothing — Restarting doesn't fix a database problem; dependency checks go in readiness, liveness looks at the process itself.
-
Unavailable code
http.Error(w, "hazır değil", http.____)
Show answer
http.Error(w, "hazır değil", http.StatusServiceUnavailable)
-
Check and question
- /livez
- Is the process alive?
- /readyz
- Can it take traffic?
- 503
- Not ready
- atomic.Bool
- Safe ready flag
Next lesson: Summary - Observability