İşletim
Sağlık
| Kontrol | Nerede | Sağlıklı | Bozuk |
|---|---|---|---|
| API | GET /health | {"status":"ok","db":"ready"} | Mongo ulaşılamazken db: "down" ile 503. API hizmet vermeye devam eder; crash-loop'a girmez. |
| Worker | konteyner healthcheck | Mongo ve Redis'e ping | — |
| Redis | redis-cli ping | PONG | API Redis olmadan açılışta 1 ile çıkar. Abonelik yazımı veritabanını bekleyebilir; 202 ile kabul edilip düşürülen push geri gelemez. |
Günlükler
docker compose logs -f api worker
Hiçbir seviyede günlükte asla görmeyecekleriniz: cihaz token'ı, FCM registration token'ı, web push endpoint'i, .p8 içeriği, service account, VAPID private key. Hatalar subscriptionId ile yazılır; bir token ayırt edilmek zorundaysa son altı karakterinin hash'i.
Yeniden başlatma ve boşaltma
docker compose stop workerSIGTERM gönderir. Worker yeni iş almayı bırakır ve uçuştakileriSHUTDOWN_TIMEOUT_MS(30 sn) içinde bitirir. Compose SIGKILL'den öncestop_grace_period: 45sbekler. İki durumda da kayıp olmaz: bitmemiş iş kuyruğa döner.- API durumsuzdur. İstediğiniz zaman yeniden başlatın.
- Zamanlanmış kampanya yeniden başlatmaları atlatır: bir süreçteki zamanlayıcı değil, Redis'te gecikmeli bir BullMQ işidir. Ayakta tutulacak scheduler servisi yoktur. Redis
appendonly yesile çalışır; iş Redis yeniden başlatmasını da atlatır.
Yedekler
| Ne | Nasıl | Neden |
|---|---|---|
Mongo mongo_data volume'u | docker compose --profile backup up -d | Abonelikler ve kullanıcılar asıl değer. Kampanya geçmişi ve olaylar olsa iyi olur. |
ENCRYPTION_KEY | parola yöneticisi | Onsuz geri yüklenen veritabanının kimlik bilgileri okunamaz. |
Redis redis_data | isteğe bağlı | Yalnızca bekleyen/zamanlanmış işler orada. Kaybı kuyruktaki gönderimleri kaybettirir, aboneleri değil. |
backup profili, her BACKUP_INTERVAL_HOURS (24) saatte mongodump --gzip --archive çalıştıran ve BACKUP_KEEP_DAYS (14) günden eski arşivleri silen bir mongo:7 sidecar'ı ekler; dosyalar mongo_backups volume'una, BACKUP_DIR ayarlıysa host'taki dizine yazılır. O dizini host dışına kopyalayın; veritabanıyla aynı diskteki yedek, yedek değildir. Geri yükleme:
docker compose --profile backup run --rm backup \
mongorestore --uri mongodb://mongo:27017 --gzip --archive=/backups/<dosya> --drop
ENCRYPTION_KEY'i döndürmek her kimlik bilgisini yeniden yüklemek demektir (yeniden mühürleme komutu yok). HMAC_SECRET'i döndürmek teslim edilmiş ama henüz açılmamış push'ların izlemesini bozar — bir kampanya yatıştıktan hemen sonra yapın.
Token hijyeni (otomatik)
- Her
410 Unregistered,BadDeviceToken,DeviceTokenNotForTopic,UNREGISTERED,SENDER_ID_MISMATCH, web404/410→ abonelikinvalidatedAtile damgalanır, kodla birliktefailedolayı yazılır vesubscription.invalidatedwebhook'u atılır. Asla tekrar denenmez. maintenancekuyruğuINACTIVE_SUBSCRIPTION_DAYS(90) boyunca etkinliği olmayan aboneliklerioptedIn: falseyapan günlük bir tarama çalıştırır. Yeniden abone olan cihaz canlanır.- Yinelenen token olamaz:
(appId, token)ve(appId, endpoint)unique partial index'lerdir. Aynı cihazdan yeniden abone olmak satırı günceller.
Veri saklama
eventsEVENT_RETENTION_DAYS(180) TTL'li time-series koleksiyondur. Kampanya sayaçları (stats) kampanyada kalıcıdır.- Idempotency kayıtları 24 saat sonra silinir.
- Denetim günlüğü süresiz tutulur.
Yükseltme
git pull && docker compose build && docker compose up -d
Index'ler her API açılışında idempotent olarak oluşturulur. Sonradan değiştirilemeyen tek şey events koleksiyonunun time-series seçenekleridir — bir kez oluşturulur; saklama süresini değiştirmek için EVENT_RETENTION_DAYS'i ayarlayıp mevcut koleksiyona collMod uygulayın ya da düşürün (olayları kaybedersiniz, sayaçları değil).
İzleme fikirleri
/healthbir dakikadan uzun 200 dışıysa uyarı.- Kampanya başına
failedolayı sayısında sıçrama — süresi dolan bir kimlik bilgisi bütün bir platformda aynı andaInvalidProviderToken/PERMISSION_DENIEDolarak görünür. - Redis belleğini izleyin; sürekli büyüyen
bull:push-*:waitlistesi worker'ın kapalı ya da aç olduğu anlamına gelir. - Panelin kampanya raporu kod başına başarısızlık tablosuna sahiptir — bir platformun neden başarısız olduğunu görmenin en hızlı yolu.