Sağlık Kontrolleri
Sağlık kontrol uç noktaları, yük dengeleyicilerin, Kubernetes gibi orkestratörlerin ve izleme sistemlerinin uygulamanızın çalışır durumda olduğunu ve trafik sunmaya hazır olduğunu doğrulamasına olanak tanır. Tipik bir kurulum iki uç nokta içerir: liveness (işlem canlı mı?) ve readiness (istek kabul etmeye hazır mı?).
Temel sağlık kontrolü
Bölüm başlığı “Temel sağlık kontrolü”200 OK döndüren basit bir sağlık uç noktası:
package main
import ( "net/http"
"github.com/gin-gonic/gin")
func main() { r := gin.Default()
r.GET("/healthz", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"status": "ok"}) })
r.GET("/ping", func(c *gin.Context) { c.String(http.StatusOK, "pong") })
r.Run(":8080")}Liveness ve readiness karşılaştırması
Bölüm başlığı “Liveness ve readiness karşılaştırması”Kubernetes ve benzeri ortamlarda genellikle iki tür sağlık kontrolüne ihtiyacınız vardır:
- Liveness probe — uygulamanın canlı olup olmadığını kontrol eder. Başarısız olursa container yeniden başlatılır.
- Readiness probe — uygulamanın trafik işlemeye hazır olup olmadığını kontrol eder. Başarısız olursa trafik geçici olarak durdurulur ancak container yeniden başlatılmaz.
package main
import ( "database/sql" "net/http" "sync/atomic"
"github.com/gin-gonic/gin" _ "github.com/lib/pq")
var isReady atomic.Bool
func main() { db, err := sql.Open("postgres", "postgres://user:pass@localhost/dbname?sslmode=disable") if err != nil { panic(err) } defer db.Close()
r := gin.Default()
// Liveness: is the process alive? r.GET("/healthz", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"status": "alive"}) })
// Readiness: can we serve traffic? r.GET("/readyz", func(c *gin.Context) { if !isReady.Load() { c.JSON(http.StatusServiceUnavailable, gin.H{"status": "not ready"}) return }
// Check database connectivity if err := db.Ping(); err != nil { c.JSON(http.StatusServiceUnavailable, gin.H{ "status": "not ready", "reason": "database unreachable", }) return }
c.JSON(http.StatusOK, gin.H{"status": "ready"}) })
// Mark as ready after initialization is complete isReady.Store(true)
r.Run(":8080")}Kubernetes yapılandırması
Bölüm başlığı “Kubernetes yapılandırması”Kubernetes dağıtım manifestinizde probe’ları yapılandırın:
apiVersion: apps/v1kind: Deploymentmetadata: name: my-gin-appspec: template: spec: containers: - name: app image: my-gin-app:latest ports: - containerPort: 8080 livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 5 periodSeconds: 10 readinessProbe: httpGet: path: /readyz port: 8080 initialDelaySeconds: 5 periodSeconds: 5Birden fazla bağımlılığı kontrol etme
Bölüm başlığı “Birden fazla bağımlılığı kontrol etme”Birden fazla bağımlılığa sahip uygulamalar için her birini kontrol edin ve ayrıntılı durum raporlayın:
package main
import ( "context" "database/sql" "net/http" "time"
"github.com/gin-gonic/gin" "github.com/redis/go-redis/v9")
type HealthChecker struct { DB *sql.DB Redis *redis.Client}
func (h *HealthChecker) CheckHealth(c *gin.Context) { ctx, cancel := context.WithTimeout(c.Request.Context(), 2*time.Second) defer cancel()
checks := gin.H{} healthy := true
// Check database if err := h.DB.PingContext(ctx); err != nil { checks["database"] = gin.H{"status": "unhealthy", "error": err.Error()} healthy = false } else { checks["database"] = gin.H{"status": "healthy"} }
// Check Redis if err := h.Redis.Ping(ctx).Err(); err != nil { checks["redis"] = gin.H{"status": "unhealthy", "error": err.Error()} healthy = false } else { checks["redis"] = gin.H{"status": "healthy"} }
status := http.StatusOK if !healthy { status = http.StatusServiceUnavailable }
c.JSON(status, gin.H{ "status": map[bool]string{true: "healthy", false: "unhealthy"}[healthy], "checks": checks, })}Test etme
Bölüm başlığı “Test etme”# Check livenesscurl -i http://localhost:8080/healthz
# Check readinesscurl -i http://localhost:8080/readyzBeklenen çıktı:
HTTP/1.1 200 OKContent-Type: application/json; charset=utf-8
{"status":"ready"}