Dağıtımları Sıfır 502 Hatasına Nasıl İndirdik
Mythex'in arka ucunu her dağıttığımızda, bir avuç istek 502 Bad Gateway ile başarısız oluyordu. Çok fazla değil, ama bir dağıtım sırasında 502, birinin tıklamasının hiçbir şey yapmadığı ya da izlediği bir derlemenin bir an takılması demektir. Bunu iki ayrı soruna kadar izledik: dağıtımlarımızla mücadele eden kendi kendini onaran bir bekçi ve bir sunucunun dinlemeyi bıraktığı an ile yük dengeleyicinin ona trafik göndermeyi bıraktığı an arasındaki boşluk. Düzeltmelerden sonra üst üste üç üretim dağıtımında sayı 10'dan 6'ya, sonra 0'a indi.
Kurulum
API'miz ve orkestratörümüz, bir AWS Application Load Balancer (ALB) arkasındaki küçük bir sunucu grubunda konteyner olarak çalışır. Bir dağıtım sunucuları birer birer günceller: eski konteynerleri boşaltır, yenilerini başlatır ve ilerler. Her sunucudaki bir bekçi, konteynerlerin ayakta olup olmadığını kontrol eder ve çalışmayan her şeyi yeniden başlatır. Amacı, gece 3'te çöken bir sürecin kimseyi uyandırmadan geri gelmesidir.
İkisi de tek başına makul. Birlikte değildiler.
Sorun 1: Bekçi dağıtımla yarıştı
Bekçi dakikada bir çalışıyor ve tek bir başarısız sağlık kontrolünde "onarıyordu". Bir dağıtım, hizmetleri kasıtlı olarak 150 saniyeye kadar boşaltır; bu sürede bir sağlık kontrolünün başarısız olması beklenir. Yani bekçi her dağıtımda tetikleniyordu.
Çoğu zaman yarışı zararsız bir şekilde kaybediyordu. Bir kez kazandı: dağıtımın ortasında compose dosyasını (hangi konteynerlerin çalışması gerektiğini tanımlayan dosyayı) yeniden yazdı ve bir sunucuyu hiç ağ geçidi konteyneri olmadan bıraktı; dağıtım işi ise başarılı bildirdi.
Düzeltmeler:
- Tek kilit. Dağıtım artık sunucunun önyükleme betiğiyle aynı dosya kilidini alıyor; böylece bekçi ve dağıtım asla aynı anda çalışamaz.
- Tek uyarı değil, dört uyarı. Bekçinin harekete geçmesi için dört ardışık başarısız kontrol gerekiyor. Boşaltılan bir hizmet artık ölü gibi görünmüyor.
- Tek tanım. Compose dosyasının artık sunuculara yayınlanan tek bir kaynağı var; birbirinden sapabilecek kopyaları yok.
- Doğrula, güvenme. Dağıtım işi artık bir komut döndü diye geçmiyor. Başarılı olabilmek için her sunucunun API'sini, orkestratörünü, ağ geçidini ve yayın çalışanını kontrol ediyor.
Sorun 2: Sunucu, trafik gitmeden ayrıldı
İkinci sorun daha sessizdi. Bir dağıtım bir sunucuyu boşalttığında, sunucu sağlık uç noktasına 503 yanıtı vermeye başlar, böylece yük dengeleyici onu rotadan çıkarır. Bizim sunucumuz bunu 5 saniye yaptı, sonra kapandı.
Ama ALB sağlığı yalnızca ara sıra kontrol ediyordu ve bir hedefe yönlendirmeyi bırakmadan önce art arda birkaç başarısız kontrol gerekiyordu; uçtan uca yaklaşık 60 saniyeye kadar. Yani yaklaşık 55 saniye boyunca yük dengeleyici, zaten dinlemeyi bırakmış bir sunucuya gerçek istekler göndermeye devam etti. Bunlar bizim 502'lerimizdi.
Düzeltme, iki zaman çizelgesini uyumlu hale getirmekti:
- Hedef grubu artık 5 saniyede bir kontrol ediyor ve 2 başarısızlıktan sonra bir hedefi sağlıksız olarak işaretliyor; fark etmesi yaklaşık 10 saniye.
- Boşaltma, sağlık kontrollerinde başarısız olmaya başladıktan sonra 15 saniye boyunca gerçek trafiğe hizmet etmeye devam ediyor; böylece her zaman bir örtüşme var.
- Bu ayarlar, biri konsoldan bir kez tıklayarak değil, altyapıyı kuran betikte yaşıyor.
Sayıların birbirini tutmasını sağlamak
Bu tür zaman aşımları birbirine bağlıdır. Boşaltma, yük dengeleyicinin fark etmek için ihtiyaç duyduğu süreden uzun sürmelidir; boşaltma artı kapanma, konteyner zorla öldürülmeden önce bitmelidir. Birinin altı ay sonra bir sayıyı değiştirip hatayı sessizce geri getirmesi kolaydır.
Bu yüzden bu ilişkileri testler olarak yazdık: boşaltma, sağlık kontrolü aralığı çarpı başarısızlık eşiğinden uzun olmalı; yeniden sağlıklı işaretlenme süresi kısa kalmalı; tüm boşaltma konteynerin durdurma bekleme süresine sığmalı. Diğer sayılar değişmeden bir sayıyı değiştirirseniz CI başarısız olur. Testlerin kendilerini de mutasyon testine tabi tuttuk: her sayıyı yanlış bir değere çevirdik ve bir testin bunu yakaladığını doğruladık.
Bir dağıtımı ölçmek kolayca yanlış yapılabilir
İlk ölçümümüz, temiz bir dağıtımın yaklaşık %3 oranında bozuk olduğunu söylüyordu. Değildi. Her 200 olmayan yanıtı sayıyorduk ve boşaltma sırasında bir sağlık uç noktasından gelen 503 bir hata değil; boşaltmanın işini yapması, yani gerçek istekleri hizmet vermeye devam ederken yük dengeleyiciye o sunucuyu seçmemesini söylemesi.
Kullanıcıların hissettiği şey 502'dir: istek hiçbir yere ulaşmamıştır. Yalnızca bunları saydığımızda gerçek tablo ortaya çıktı: üç üretim dağıtımında 10, sonra 6, sonra 0.
Bundan çıkardıklarımız
- Kendi kendini onarma, planlı kesintileri bilmek zorundadır. Bir dağıtımı bir çökmeden ayırt edemeyen bir bekçi, sonunda dağıtımla kavga eder.
- Boşaltma bir el sıkışmadır. Sunucu, yük dengeleyicinin trafik göndermeyi kanıtlanabilir biçimde bıraktığı ana kadar hizmet vermeye devam etmelidir; bu zamanlama sunucuda değil, dengeleyicide ayarlanır.
- Değişmezleri testlere dönüştürün. Operasyonel sayılar zamanla kayar. Birbirleriyle ilişkilerini test eden testler kaymaz.
- Ölçmeden önce neyi ölçtüğünüze karar verin. "Hatalar" yanlış metrikti; "hiçbir yere ulaşmayan istekler" doğru olandı.
Mythex'te bir uygulama yayınlıyorsanız, bunların hiçbiri size görünmez; amaç da budur. İlgili: yayınladığınız uygulama, yeniden yayınlarken nasıl ayakta kalır.