Canary deployment membatasi paparan bug baru ke sebagian kecil pengguna sebelum versi aplikasi dirilis secara global. Jika versi canary mengalami regresi kinerja—seperti peningkatan HTTP 5xx atau lonjakan latensi p99—sistem harus memicu rollback otomatis tanpa intervensi manual. Artikel ini membahas implementasi instrumentasi Prometheus pada aplikasi Go Fiber, penyusunan kriteria evaluasi metrik, serta konfigurasi otomasi rollback.
1. Instrumentasi Metrik HTTP di Go Fiber
Untuk memantau kesehatan canary release secara objektif, aplikasi harus mengekspos metrik throughput, error status, dan latensi yang dilabeli dengan versi rilis (misalnya stable vs canary). Hindari label dengan kardinalitas tinggi seperti ID pengguna atau raw URL path tanpa normalisasi.
Gunakan pustaka prometheus/client_golang bersama middleware custom Go Fiber berikut untuk mengumpulkan data metrik:
package main
import (
"strconv"
"time"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/adaptor"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
httpRequestsTotal = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total HTTP requests processed by Go Fiber",
},
[]string{"version", "method", "route", "status"},
)
httpDurationHistogram = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "HTTP request latency distributions in seconds",
Buckets: []float64{0.005, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5},
},
[]string{"version", "method", "route"},
)
)
func init() {
prometheus.MustRegister(httpRequestsTotal, httpDurationHistogram)
}
func MetricMiddleware(appVersion string) fiber.Handler {
return func(c *fiber.Ctx) error {
start := time.Now()
err := c.Next()
duration := time.Since(start).Seconds()
status := c.Response().StatusCode()
route := c.Route().Path
if route == "" {
route = "unmatched"
}
method := c.Method()
statusStr := strconv.Itoa(status)
httpRequestsTotal.WithLabelValues(appVersion, method, route, statusStr).Inc()
httpDurationHistogram.WithLabelValues(appVersion, method, route).Observe(duration)
return err
}
}
func main() {
app := fiber.New()
// Set version dari environment variable atau build flag
appVersion := "canary-v1.2.1"
app.Use(MetricMiddleware(appVersion))
app.Get("/metrics", adaptor.HTTPHandler(promhttp.Handler()))
app.Get("/checkout", func(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusOK)
})
app.Listen(":3000")
}Catatan: Gunakan
c.Route().Pathketimbangc.Path()untuk menghindari ledakan kardinalitas metrik akibat parameter dinamis seperti/users/123.
2. Skenario Insiden: Regresi Kode pada Versi Canary
Misalkan commit terbaru pada endpoint /checkout mengandung bug pelepasan koneksi database pool yang tidak sempurna (connection leak). Pada uji unit lokal, koneksi ditutup normal. Namun saat pod canary menerima 10% beban trafik riil di cluster:
- Pool koneksi database pada pod canary habis dalam 45 detik.
- Go Fiber mulai menghasilkan HTTP status
500 Internal Server Errorsecara masif pada pod canary. - Latensi p99 meroket dari 45ms ke 3200ms akibat thread/goroutine menunggu connection timeout.
Versi stable (v1.2.0) tetap sehat. Tanpa observasi berbasis metrik canary yang terpisah, kegagalan ini akan menginfeksi seluruh armada pod begitu deployment dinaikkan ke 100%.
3. Kriteria Evaluasi dan Otomasi Rollback
Dua metrik utama penentu kegagalan rilis adalah HTTP 5xx Error Rate dan p99 Latency. Rollback otomatis harus dieksekusi jika salah satu kondisi berikut terpenuhi selama interval observasi minimal 60 detik:
- Error Rate 5xx pada versi canary melebihi 1.5% dari total trafik canary.
- p99 Latency pada versi canary melebihi batas SLA (misal: > 500ms).
Prometheus Alert Rules
Berikut adalah konfigurasi alerting rule pada Prometheus untuk mendeteksi degradasi canary:
groups:
- name: canary_evaluation_rules
rules:
- alert: CanaryHighErrorRate
expr: |
(
sum(rate(http_requests_total{version=~"canary.*", status=~"5.."}[1m]))
/
sum(rate(http_requests_total{version=~"canary.*"}[1m]))
) * 100 > 1.5
for: 1m
labels:
severity: critical
action: rollback
annotations:
summary: "Canary error rate melampaui batas toleransi 1.5%"
- alert: CanaryHighLatencyP99
expr: |
histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{version=~"canary.*"}[1m])) by (le))
> 0.5
for: 1m
labels:
severity: critical
action: rollback
annotations:
summary: "Canary p99 latency di atas 500ms"Eksekusi Rollback via Progressive Delivery Tool (Argo Rollouts / Flagger)
Dalam pipeline modern berbasis Kubernetes, alert Prometheus dihubungkan langsung ke progressive delivery operator seperti Argo Rollouts. Analisis metrik dijalankan secara deklaratif:
apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
name: fiber-canary-success-rate
spec:
metrics:
- name: error-rate
interval: 30s
successCondition: result[0] <= 1.5
failureLimit: 2
provider:
prometheus:
address: http://prometheus-k8s.monitoring:9090
query: |
(
sum(rate(http_requests_total{version="canary-v1.2.1", status=~"5.."}[1m]))
/
sum(rate(http_requests_total{version="canary-v1.2.1"}[1m]))
) * 100Jika metrik melanggar successCondition sebanyak 2 kali berturut-turut (failureLimit: 2), controller langsung membatalkan canary, mengarahkan 100% traffic kembali ke pod stable, dan mengubah status deployment menjadi Degraded.
4. Analisis Postmortem: Failure Mode & Isolasi Dampak
Setelah rollback instan selesai, tim engineer melakukan triage insiden dengan fokus pada titik kegagalan berikut:
- Root Cause Analysis (RCA): Gunakan profiling runtime Go (pprof) untuk meninjau goroutine stack. Dalam skenario di atas, ditemukan penumpukan goroutine pada panggilan
sql.DB.Conn()akibat penanganan context cancellation yang salah di handler Fiber. - Failure Mode Handler: Pastikan seluruh handler Go Fiber mengimplementasikan timeout context eksplisit (
context.WithTimeout) dan recover middleware untuk menahan panic agar tidak mematikan process container:
app.Use(recover.New())
app.Use(limiter.New(limiter.Config{
Max: 1000,
Expiration: 1 * time.Minute,
}))- Isolasi Dampak: Karena trafik dibatasi 10% dan rollback dieksekusi dalam 90 detik, dampak terbatas pada kurang dari 0.15% dari total seluruh transaksi harian. Sistem database utama tidak mengalami cascading failure berkat pemutusan beban canary lebih awal.
5. Pencegahan Jangka Panjang
Otomasi rollback hanyalah lapisan pertahanan terakhir. Untuk memperkuat keandalan rilis di masa depan:
- Synthetic Smoke Test Pasca-Deploy: Sebelum pod canary menerima live public traffic, kirimkan synthetic probes ke endpoint privat untuk memvalidasi alokasi resource dan dependensi downstream.
- Automated Canary Analysis (ACA) Bertahap: Jalankan transisi bertahap (1% → 5% → 25% → 50% → 100%) dengan durasi evaluasi metrik 5–10 menit per fase. Evaluasi metrik menggunakan baseline komparatif (metrik canary dibandingkan langsung dengan metrik stable pada rentang waktu yang sama, bukan angka statis).
- Graceful Degradation: Terapkan circuit breaker (misal: via library
sony/gobreaker). Ketika downstream error meningkat, handler Fiber harus memberikan fallback response (cache atau degradasi fungsi parsial) daripada melemparkan error 500 ke pengguna akhir.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!