PushizoDocs
OperasyonRunbook'lar

Go dispatcher

ADR-0026 §3. Push gönderimini (APNs, FCM, HMS, Web Push) Go servisine (services/dispatcher) taşır; render, sahiplenme ve sonuç uygulama worker'da kalır. İsteğe bağlıdır ve anında geri alınır: DISPATCHER_GO_CHANNELS…

docs/adr/0026-olcek-mimarisi.md. Push gönderimini (APNs, FCM, HMS, Web Push) Go servisine (services/dispatcher) taşır; render, sahiplenme ve sonuç uygulama worker'da kalır. İsteğe bağlıdır ve anında geri alınır: DISPATCHER_GO_CHANNELS boşken tüm gönderim TS sağlayıcılarıyla yapılır. Teknik ayrıntı ve köprü sözleşmesi: services/dispatcher/README.md.

Etkinleştirme

  1. Ön koşul: Go servisi worker ile aynı MASTER_KEY, DATABASE_URL ve REDIS_URL değerlerini kullanır. Sunucu saatleri NTP ile eşit olmalı (son tarih karşılaştırması iki taraflıdır).
  2. Servisi başlat:
    • Compose: docker compose --env-file .env.prod -f infra/compose/docker-compose.prod.yml --profile go-dispatcher up -d dispatcher
    • Kubernetes: chart'a dispatcher Deployment'ı eklenene kadar imaj ghcr.io/exec0de/pushizo-dispatcher ayrı Deployment olarak çalıştırılır (değerler aşağıda).
  3. Hazır olduğunu doğrula: konteyner sağlıklı (/dispatcher healthcheck), GET :4002/readyz → ready; Redis'te ZRANGE hs:dispatch-go:alive:ios_push 0 -1 WITHSCORES örnek adını gösterir.
  4. Kanalları sırayla aç: worker-dispatch için DISPATCHER_GO_CHANNELS=web_push (en düşük riskli) → izle → ekle (ios_push,android_push,hms_push,web_push). Worker yeniden başlatılır (değişken açılışta okunur).
  5. İzle (en az bir kampanya döngüsü): aşağıdaki metrikler; teslimat oranı ve hata kodları önceki günle aynı olmalı.

DISPATCHER_GO_FALLBACK=true (varsayılan) iken canlı Go örneği yoksa batch TS sağlayıcısıyla gönderilir (dispatcher_go_requests_total{outcome="fallback"}); Go servisi dağıtım sırasında kısa süre kapansa da gönderim durmaz. false yapılırsa Go yokken batch'ler akışta bekler ve zaman aşımında geçici hata alıp yeniden denenir.

Geri dönüş

DISPATCHER_GO_CHANNELS= (boş) yapıp worker-dispatch'i yeniden başlatın: sonraki batch'ten itibaren TS sağlayıcıları kullanılır. Akışta kalan istekler son tarihi geçince Go servisi tarafından gönderilmeden silinir; yanıt beklenirken worker kapanırsa ilgili batch geçici hata olarak yeniden denenir (yinelenen bildirim üretmez). Go servisi ayrıca durdurulabilir; kanal tek tek de geri alınabilir.

Metrikler

MetrikKaynakAnlam / eşik
provider_send_total{provider,outcome}Go (Go modundaki kanallar) / worker (TS modu)Aynı ad ve etiketler; Go modunda worker yazmaz (çift sayım yok). auth ve invalid_token oranı önceki dönemle karşılaştırılır
provider_latency_seconds{provider}Go / workerBatch gönderim süresi; p95 TS dönemine yakın veya altında olmalı
dispatcher_go_requests_total{channel,outcome}workerok; timeout > 0 ise Go servisi yetişemiyor/çalışmıyor; rejected sözleşme/sürüm uyuşmazlığı; fallback canlı örnek yok
dispatcher_go_roundtrip_seconds{channel}workerXADD → yanıt süresi; DISPATCHER_GO_TIMEOUT_MS'e yaklaşıyorsa ölçekleyin
dispatcher_go_batches_total{channel,outcome}Gook; stale (son tarihi geçmiş istek, gönderilmedi), invalid, error (kimlik bilgisi/DB)
dispatcher_go_inflight_batches{channel}GoDISPATCHER_MAX_BATCHES sınırına dayanıyorsa replika veya sınır artırılır

Prometheus compose'da pushizo-dispatcher işiyle (DNS keşfi; servis yoksa hedef oluşmaz) toplar.

Sorun giderme

BelirtiOlası nedenYapılacak
Açılışta aktif veri anahtarı MASTER_KEY ile çözülemediGo servisine farklı MASTER_KEY verilmişWorker/API ile aynı değeri verin (gizli yöneticiden)
Teslimatlarda GO_DISPATCHER_TIMEOUTGo servisi kapalı (yedek kapalı), aşırı yük, Redis gecikmesireadyz, dispatcher_go_inflight_batches; replika ekleyin veya DISPATCHER_MAX_BATCHES artırın; acilse geri dönüş
GO_CREDENTIALS / GO_DATABASE hata kodlarıGo servisi satırı okuyamıyor/çözemiyor (DB erişimi, RLS rolü, anahtar)Servis logu (kimlik bilgisi çözülemedi); kanal invalid yapılmaz, batch'ler yeniden denenir
GO_CONFIG_CHANGEDGönderim sırasında kanal yapılandırması değiştiKendiliğinden düzelir (yeniden denemede yeni yapılandırma)
GO_DISPATCHER_REJECTEDWorker ve Go servis sürümleri farklı protokol konuşuyorİki bileşeni aynı sürüme getirin
stale artıyorWorker'lar zaman aşımına uğramış istekleri bırakıyor; saat kaymasıNTP, DISPATCHER_GO_TIMEOUT_MS, Go kapasitesi
hs:dispatch-go:* akışı büyüyorGo servisi kanal akışını okumuyor (DISPATCHER_CHANNELS eksik)Kanal listesini düzeltin; akış ~100k girdide kırpılır

Kimlik bilgisi Redis'e yazılmaz; akış girdilerinde yalnızca render edilmiş içerik, cihaz belirteci ve config_id bulunur. Go servisi channel_configs satırını RLS etkin işlemde (app.current_app_id) ve app_id filtresiyle okur.

Kubernetes değerleri (chart'a eklenecek)

Dispatcher Deployment'ı için: imaj pushizo-dispatcher, port 4002 (/healthz liveness, /readyz readiness, /metrics ServiceMonitor), ortam DATABASE_URL, REDIS_URL, MASTER_KEY (ExternalSecret), NODE_ENV=production, DISPATCHER_CHANNELS, DISPATCHER_MAX_BATCHES, WEB_PUSH_EXTRA_HOSTS; terminationGracePeriodSeconds: 45, readOnlyRootFilesystem: true, runAsNonRoot (UID 65532); NetworkPolicy çıkışı: Postgres, Redis ve sağlayıcılar (443). Worker-dispatch için DISPATCHER_GO_CHANNELS, DISPATCHER_GO_TIMEOUT_MS, DISPATCHER_GO_FALLBACK.

Bu sayfada