63. gRPC Health Checking Standar: Modern Approach for Microservices Reliability
Ketika membangun sistem terdistribusi berbasis microservices, memastikan setiap layanan berjalan dengan baik adalah hal krusial. Kegagalan satu service bisa berdampak ke keseluruhan sistem. Untuk itu, health check menjadi fondasi penting. Namun, bagaimana cara melakukan health check pada service berbasis gRPC, protokol RPC modern pilihan para engineer?
Di artikel ini, saya akan bahas standar gRPC Health Checking — termasuk konsep, implementasi, simulasi, contoh kode, dan best practice yang sudah banyak diadopsi industri.
Kenapa Health Check pada gRPC Penting?
Pada aplikasi tradisional HTTP/REST, health check biasanya cukup mudah: expose endpoint seperti GET /healthz yang mengembalikan status layanan (200 OK, 503 Service Unavailable, dst). Load balancer atau orchestrator seperti Kubernetes lalu menggunakan endpoint tersebut untuk memantau dan men-deploy ulang service yang gagal.
Namun, pada arsitektur gRPC, service hanya expose port binary, bukan endpoint HTTP. Tidak ada standar universal untuk health check seperti halnya pada REST API. Tanpa health check, orchestrator tidak tahu kapan harus mengganti atau memperbaiki instance service.
Di sinilah gRPC Health Checking Protocol (atau Health Checking Standard) berperan penting.
Standar gRPC Health Checking
gRPC Health Checking Protocol adalah standar terbuka untuk memeriksa status layanan gRPC. Standar ini didefinisikan sebagai sebuah service dengan nama grpc.health.v1.Health. Service ini memiliki method-method sederhana, yang memudahkan klien (load balancer, sidecar, orchestrator) untuk mengecek status service.
Definisi Protobuf
Berikut adalah definisi service health-check menurut protokol standar:
syntax = "proto3";
package grpc.health.v1;
service Health {
// Cek status satu service
rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
// Streaming status secara kontinu
rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse);
}
message HealthCheckRequest {
string service = 1;
}
message HealthCheckResponse {
enum ServingStatus {
UNKNOWN = 0;
SERVING = 1;
NOT_SERVING = 2;
SERVICE_UNKNOWN = 3; // status untuk service yang belum diketahui, hanya digunakan oleh Watch.
}
ServingStatus status = 1;
}
- Check: Klien mengirimkan nama service, mendapat status SERVING/NOT_SERVING.
- Watch: Klien bisa subscribe perubahan status secara realtime (misal, untuk load balancer/sidecar).
Tabel status:
| Status | Arti |
|---|---|
| UNKNOWN | Status tidak diketahui |
| SERVING | Service dalam keadaan sehat dan siap menerima request |
| NOT_SERVING | Service sedang bermasalah (maintenance, sedang restart, dsb) |
| SERVICE_UNKNOWN | Service dengan nama itu tidak ditemukan (khusus Watch stream) |
Diagram Alur Health Checking
Mari visualisasikan proses health check dengan diagram mermaid berikut:
sequenceDiagram
participant Orchestrator as Orchestrator / Load Balancer
participant Service as gRPC Service
Orchestrator->>Service: Health.Check(serviceName)
Service-->>Orchestrator: HealthCheckResponse(SERVING / NOT_SERVING)
Note right of Orchestrator: Decision
Based on response
Implementasi Health Check pada Language Client & Server
Implementasi di Server Go
Pada gRPC ecosystem tersedia standard implementation untuk health checking, misal di Go (google.golang.org/grpc/health).
1. Server Setup
Misal, Anda punya service seperti di bawah ini:
package main
import (
"context"
"google.golang.org/grpc"
"google.golang.org/grpc/health"
healthpb "google.golang.org/grpc/health/grpc_health_v1"
"net"
"log"
)
func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
// Buat instance gRPC health check
healthServer := health.NewServer()
// Tandai server ini SERVING status awal
healthServer.SetServingStatus("", healthpb.HealthCheckResponse_SERVING)
healthpb.RegisterHealthServer(s, healthServer)
log.Println("gRPC server with healthcheck running at :50051")
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
2. Simulasi: Ubah Status Health Check
Misalkan saat maintenance, Anda ingin men-declare layanan tidak sehat (NOT_SERVING). Anda cukup update status dengan method SetServingStatus:
// Notifikasi orchestrator dan load balancer service sedang maintenance
healthServer.SetServingStatus("", healthpb.HealthCheckResponse_NOT_SERVING)
Client: Simulasi Health Check dengan Go
Sebagai client (misal load balancer, kubernetes-probe, dsb), Anda cukup panggil method berikut:
import (
"context"
"google.golang.org/grpc"
healthpb "google.golang.org/grpc/health/grpc_health_v1"
"log"
"time"
)
func main() {
conn, err := grpc.Dial(":50051", grpc.WithInsecure())
if err != nil {
log.Fatal("fail connect:", err)
}
defer conn.Close()
hc := healthpb.NewHealthClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
res, err := hc.Check(ctx, &healthpb.HealthCheckRequest{Service: ""}) // Empty = seluruh server
if err != nil {
log.Fatalf("could not check health: %v", err)
}
log.Printf("Health status: %s", res.Status)
}
Integrasi dengan Kubernetes
Di Kubernetes, probe HTTP bukan solusi ideal untuk gRPC. Namun, dengan standar gRPC health, Kubernetes >=v1.23 sudah mendukung grpc.health/v1:
livenessProbe:
grpc:
port: 50051
readinessProbe:
grpc:
port: 50051
Hasil: Kubernetes langsung tanya ke service via health protocol, tanpa HTTP endpoint tambahan.
Best Practice dan Tips
Selalu Expose Health Service
Semua gRPC service disarankan menjalankan standar health check. Banyak framework sudah menyediakan otomatisasi ini.Granular Health Checking
Anda bisa gunakan namaservicepada request untuk granularitas status (misal: database, cache).Dynamic Status
Dinamis update status health secara periodik, misal jika gagal konek ke dependency (DB down, dsb).Gunakan Stream Watch
Jika environment Anda support, manfaatkan Watch untuk notifikasi real-time status service.Security Concern
Untuk keamanan, expose hanya pada internal network atau gunakan mTLS antara orchestrator dan service.
Studi Kasus: Health Check untuk Multiple Dependencies
Misal, gRPC service Anda tergantung pada beberapa database. Anda bisa buat proses checker seperti berikut (pseudo-code):
go func() {
for {
if db.Ping() == nil && redis.Ping() == nil {
healthServer.SetServingStatus("", healthpb.HealthCheckResponse_SERVING)
} else {
healthServer.SetServingStatus("", healthpb.HealthCheckResponse_NOT_SERVING)
}
time.Sleep(time.Second)
}
}()
Dengan ini, status health akan selalu update secara live.
Kesimpulan
gRPC health checking standard adalah solusi modern untuk reliability application microservices. Ia membantu load balancer, orchestrator, dan monitoring system untuk mendeteksi dini kegagalan tanpa harus menambah endpoint HTTP baru. Dengan standar ini, Anda bisa menghadirkan arsitektur yang robust, maintainable, dan future-proof.
Jangan lupa: reliability aplikasi Anda adalah hasil dari disiplin menerapkan standar seperti ini!
Referensi:
Selamat mencoba, show the world your healthy microservices! 🚀