Blog

Sunucu Başına Değil, Bir Kez Tetiklenen Uyarılar

Operasyonel uyarılarımızdan biri, bir oluşturucunun yayınlanmış uygulaması için "düşük kredi" uyarısı, ekibimize en fazla günde bir kez ulaşmak üzere tasarlandı. Bir öğleden sonra beş kez geldi. Nedeni: API'nin her kopyası hangi uyarıları gönderdiğini kendi belleğinde tutuyordu; bu yüzden iki sunucu uyarıyı iki kez gönderdi ve her dağıtım bu belleği silip uyarının yeniden gönderilmesine izin verdi. Aynı kalıp bir arka plan işinin de işi iki kez yapmasına neden oluyordu. Artık ikisi de paylaşılan bir depo üzerinden koordine oluyor ve depo erişilemez olduğunda güvenli tarafta kalıyor.

Belirti

Mythex, bir şeye bakılması gerektiğinde ekibine uyarılar gönderir: bir servis çalışmıyorsa, bir iş takılmışsa ya da bir oluşturucunun yayınlanmış uygulamasının kredi bakiyesi azalıyorsa. Her uyarının bir tekilleştirme penceresi vardır: aynı uyarının yalnızca bir kez gönderildiği bir süre. Düşük kredi uyarısı için bu pencere 24 saattir.

Bir öğleden sonra aynı uyarının beş kopyasının gelmesi, pencerenin tutmadığı anlamına geliyordu. Daha kötüsü, bunlar yaklaşık 11 dakika arayla çiftler halinde geliyordu.

Neden oldu

Uyarılar paketimizdeki tekilleştirme, bellekte tutuluyordu: çalışan süreç içinde bir tablo, "uyarı anahtarı → en son ne zaman gönderildi". Tek bir sürecin hiç yeniden başlamadığı durumda bu işe yarar. Üretimde ikisi de yok:

  • İki API replikası. Üretimde API'nin iki kopyası çalışır. Her birinin kendi tablosu vardı, dolayısıyla her biri uyarıyı bir kez gönderdi. İşte çiftler bu.
  • Dağıtımlar. Her dağıtım her iki replikayı da boş tablolarıyla yeni süreçlerle değiştirir. Dağıtımdan sonra uyarı, hiç gönderilmemiş gibi yeniden gitti.

Her çift içindeki yaklaşık 11 dakikalık aralık, bu uyarıyı tetikleyen işten geliyordu. İş her iki replikada da çalışıyor ve bir kilit alıyor; bu yüzden replikalar sırayla kazanıyor ve her biri sırası geldiğinde uyarıyı tetikliyordu.

Aynı kodda ikinci, daha sessiz bir hata daha vardı. Tablonun sonsuza kadar büyümesini önlemek için, 500 anahtara ulaştığında kendini temizliyordu: pencereye bakmadan 15 dakikadan eski her girişi siliyordu. Yoğun yükte, 24 saatlik bir tekilleştirme çeyrek saat sürebiliyordu.

Düzeltme

Uyarı başına paylaşılan tek bir kayıt

API bir uyarı göndermeden önce, uyarının tekilleştirme anahtarını Redis'te talep ediyor. Redis, hem iki replikanın hem de API yeniden başlasa bile kaybolmayan paylaşılan bir bellek içi depodur. Talep, tek bir "bu anahtarı yalnızca yoksa ayarla ve pencere sonunda süresi dolsun" işlemidir. Anahtarı ilk talep eden replika uyarıyı gönderir; diğeri anahtarın alındığını görür ve sessiz kalır. Dağıtımdan sonra yeni bir süreç, anahtarın hâlâ orada olduğunu görür.

Anahtar ve pencere, uyarı paketinin kullandığı aynı kuraldan gelir; artık ikisi arasında paylaşılıyor, bu yüzden iki katman "aynı uyarı"nın ne olduğu konusunda anlaşmazlığa düşemez.

Kapalı değil, açık başarısız ol

En önemli karar, Redis'e ulaşılamadığında ne yapılacağıydı. Uyarıyı yine de göndermeyi seçtik. Redis kapalıysa ya da 1,5 saniye içinde yanıt vermezse uyarı gider. Yinelenen bir uyarı gürültüdür. Kaybolan bir uyarı ise birine haber verilmemesi demektir.

En ciddi uyarılar, P0'lar, tekilleştirme tarafından hiç tutulmaz.

Her girişin kendi penceresi var

Uyarı paketinin kendi bellek içi tekilleştirmesinde, her girişe artık penceresinin ne zaman bittiği yazılıyor ve temizlik yalnızca penceresi bitmiş girişleri kaldırıyor. 24 saatlik bir anahtar, başka kaç uyarı gelirse gelsin 24 saat kalır.

Aynı hata, başka bir yerde

Aynı kalıp, bir arka plan işini de iki katına çıkarmıştı: her çalışma alanının durumuna dair kaydımızı sandbox sağlayıcımızın durumuyla uyumlu tutan bir mutabakat işi. Her geçişte hesaptaki her sandbox'ı listeliyor (üretimde binlerce, yaklaşık beş saniye) ve çalışan ya da duraklatılmış her projeyi de ekliyor. Her iki replika bunu her iki dakikada bir çalıştırıyordu.

Yazmaları idempotent, yani bir kez ya da iki kez çalıştırmak aynı sonucu veriyor; bu yüzden hiçbir şey bozulmadı. Sadece iş iki katına çıkmıştı. Artık her iki dakikalık pencere, kullanım ölçerlerimizin zaten talep ettiği şekilde Redis'te talep ediliyor ve geçişi yalnızca talebi alan replika çalıştırıyor. Redis'e ulaşılamazsa, geçiş yine de çalışıyor: işi iki kez yapmak zararsızdır, yapmamak ise değildir.

Nasıl test ettik

Testler gerçek kurulumu modelliyor. Uyarı modülünü iki kez yükleyip iki ayrı "replika" gibi tek bir paylaşılan depoya bağlıyoruz, her birinden aynı uyarıyı tetikliyoruz, ardından "dağıtımdan sonra"yı temsil etmek için üçüncü, yeni bir kopya yükleyip yeniden tetikliyoruz. Tam olarak bir uyarı gönderiliyor. Diğer testler, farklı bir oluşturucunun uyarısının hâlâ gittiğini, bir P0'ın her iki replikadan da gönderildiğini ve depo kapalıysa ya da zaman aşımını geçecek kadar yanıt vermezse uyarının yine gönderildiğini kontrol ediyor. Temizlik düzeltmesinin kendi testi var: 24 saatlik bir anahtar, 20 dakika sonra gelen 600 başka uyarıdan sonra da hayatta kalıyor.

Mutabakat işi için, aynı anda tetiklenen iki replika ve aynı pencerede üçüncü bir tetikleme, tek bir listeleme üretiyor.

Öğrendiklerimiz

  • Bellek içi durum süreç başınadır. Sunucular arasında doğru kalması gereken her şey, "bir kez gönderildi" ya da "bir kez çalıştı", paylaşılan bir yerde tutulmalıdır.
  • Dağıtımlar yeniden başlatmadır. Bir sonraki yeniden başlatmaya kadar dayanan durum, sıradan bir çalışma gününü bile atlatamaz.
  • Hangi yöne başarısız olacağına karar verin. Uyarılar için paylaşılan bir deponun kapalı olması, daha az değil, daha fazla uyarı anlamına gelmelidir.
  • Yalnızca örneğe değil, kalıba bakın. Uyarı en göze batan vakaydı; iki katına çıkan mutabakat işi aynı hataydı, sessizce iş israf ediyordu.

Bunların hiçbiri Mythex'in içinden görünmez. Platformu nasıl sabit tuttuğumuz hakkında daha fazlası için dağıtımlarda sıfır 502 hatasına nasıl ulaştık ve eksik swap dosyası yazılarına bakın. Bir servisin birden fazla kopyasını çalıştırma fikrine yeniyseniz, sunucu nedir rehberimiz temelleri anlatır.

Mythex · Pricing · Yapay zekayla her şeyi yapın · Web sitesi ve uygulama şablonları · Mythex karşılaştırmaları · Yapay zekayla uygulama geliştirme sözlüğü · Yapay zekayla uygulama geliştirme için ücretsiz araçlar · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)