Başarısız Bir Yeniden Yayın, Çalışan Bir Arka Ucu Asla Silmez
25 Eylül'de, başarısız bir yeniden yayın, bir uygulamanın yaklaşık iki buçuk saattir canlı olan ve düzgün çalışan arka ucunu sildi. Başarısız bir yayını geri alan kod, yayının dokunduğu her sunucu uygulamasını kaldırdı; yayın başlamadan önce zaten hizmet veren uygulamalar da dahil. Artık yalnızca bir yayının oluşturduğu uygulamalar silinebiliyor; önceden var olan bir uygulama ise, çalıştığı tam sürüme geri döndürülüyor. Aynı gün yapılan iki takip düzeltmesi, bu geri almanın barındırma platformunun kendi dağıtım aracı başarısız olduğunda da çalışmasını sağladı ve uyuyan bir uygulamanın sadece uyuduğu için başarısız sayılmasını engelledi.
Bir arka uç nasıl yayınlanır
Mythex uygulamanızın bir arka ucu olduğunda (yalnızca statik dosyalar değil, bir API ya da sunucu), yayınlama bir Dockerfile'dan (uygulamayı bir imaja paketleyen bir tarif) inşa edilir ve bu imaj platformumuzun makinelerine dağıtılır. Ardından bir sağlık kontrolü, yeni sürümün gerçekten ayağa kalkıp ayakta kaldığını doğrulayana kadar bekler; ancak bundan sonra yayın canlı olarak işaretlenir.
Bu süreçte bir şey başarısız olursa, bunu geri almak için bir geri alma çalışır. Bu geri almanın doğru yapılması, yayıncılıkta neredeyse her şeyden daha önemlidir; çünkü tam da bir şeylerin ters gittiği anda çalışır.
Sorun 1: geri alma, geri yüklemesi gerekeni sildi
Geri alma, bir yayının dağıttığı sunucu uygulamalarının bir listesini tutuyordu ve başarısızlık durumunda bu listedeki her birini yok ediyordu. İlk yayın için bu doğru: uygulama birkaç dakika önce oluşturuldu, hiçbir şey ona bağlı değil ve silmek her şeyi olduğu gibi bırakıyor.
Ama yeniden yayın için tam tersi yanlış. Uygulama zaten vardı ve gerçek ziyaretçilere hizmet veriyordu. 25 Eylül'de, yaklaşık iki buçuk saattir canlı olan bir uygulamanın API'si, başarısız bir yeniden yayın tarafından silindi.
Aynı kodda ikinci bir hata moduna da rastlandı. Silme işlemi tamamlanamadığında, bozuk yeni imaj makinelerde kalıyordu; oysa uygulama sahibine mevcut sitelerinin hâlâ canlı olduğunu söylüyorduk. Sağlık kontrolünün başarısız olabileceği noktaya gelindiğinde, yeni imaj zaten her makineye dağıtılmış oluyor. Hiçbir şey yapmamak, geri almak anlamına gelmiyor.
Düzeltme: yalnızca oluşturduğunu yok et, geri kalanı geri yükle
Artık her yayın, dokunduğu her sunucu uygulaması için şunları kaydediyor:
- Bu yayının uygulamayı oluşturup oluşturmadığını, ve
- oluşturmadıysa, bundan hemen önce hangi imajı çalıştırdığını.
Başarısızlıkta her uygulama üç işlemden birini görüyor:
- Bu yayın tarafından oluşturulmuş: eskisi gibi yok et.
- Zaten vardı, önceki imaj biliniyor: önceki imajı aynı yapılandırmayla yeniden dağıt. Yeniden inşa yok; yalnızca imaj geri taşınıyor.
- Zaten vardı, önceki imaj bilinmiyor: dokunma. Var olan bir uygulama, geri yüklenemese bile asla silinmez.
Bu kurallar, kendi testleri olan küçük bir saf fonksiyon. Bu sayede karar, bir test başarısız olmadan "her şeyi yok et" noktasına geri kayamaz.
Sorun 2: dağıtım aracı, geri almayı kaydetmeden önce başarısız olabilirdi
Bu düzeltmeden kısa süre sonra, içinde bir boşluk bulduk. Barındırma platformunun dağıtım aracı kendi duman testlerini çalıştırıyor: yeni makineler çökerse hata ile çıkıyor. Ama bunu, yeni imaj zaten makinelerdeyken yapıyor.
Kodumuz, bir uygulamayı geri alma listesine yalnızca araç başarıyla döndüğünde ekliyordu. Araç dağıtımın kendisi başarısız olduğunda, uygulama henüz listede değildi ve hiçbir şey geri yüklenmedi. Staging ortamımızda, bozuk bir yeniden yayın, bozuk imajı hizmet vermeye devam ettirdi.
Düzeltme: geri almayı başlamadan önce kaydet
Uygulama artık hazırlandığı anda ve üzerine hiçbir şey dağıtılmadan önce, geri alma listesine kaydediliyor; oluşturulup oluşturulmadığı ve hangi imajı çalıştırdığı bilgisiyle birlikte. Sonrasında ne başarısız olursa olsun, geri almanın neyi geri koyacağını bilmesi gerekiyor. Bunu yerelde doğruladık: bozuk bir yeniden yayın, dağıtım aracının kendi duman testlerinde başarısız oldu ve önceki sürüm yanıt vermeye devam etti.
Sorun 3: uyuyan bir uygulama "hiç başlamadı" diye başarısız sayıldı
Mythex'te yayınlanan uygulamalar, kredilerinizi korumak için boşta kaldıklarında uyur. Yeniden yayın, uyuyan bir makineyi durmuş halde bırakır; bu yüzden sağlık kontrolünün onu uyandırması gerekir. Kontrol, platformdan makineyi başlatmasını bir kez istiyordu ve yanıtı yok sayıyordu.
25 Eylül'de, bu tek başlatma isteği boşa gitti. Sağlıklı bir API, beş dakikalık sağlık kontrolü boyunca durmuş halde bekledi ve "1 makine hiç başlamadı (son durum: stopped)" hatasıyla başarısız sayıldı.
Platform bazen başlatmayı reddediyor. Bu sorunu yeniden üretirken, biz tetiklemeden "lease currently held" çakışması döndürdü; bir makine güncellenirken de başlatmaları reddediyor.
Düzeltme: pes etme, kapıyı çal
Sağlık kontrolü artık:
- beklerken, durmuş bir makineyi başlatmak için her 20 saniyede bir tekrar soruyor,
- platform reddettiğinde ne yanıtladığını kaydediyor ve
- uygulamaya, bir ziyaretçinin yapacağı gibi, tek bir normal istek gönderiyor. Platformun proxy'si uyuyan bir makineye bir istek geldiğinde onu uyandırıyor.
İlk başlatması reddedilen, gerçek platformda kullandığımız tek amaçlı bir uygulamayla yeniden ürettik. Düzeltmeden önce yayın 91 saniye sonra başarısız oldu. Düzeltmeden sonra ise 20 saniyede yayınlandı. Gerçekten açılışta çöken bir uygulama yine başarısız olur; olması gerektiği gibi.
Öğrendiklerimiz
- Geri almanın yeni ile var olan arasındaki farkı bilmesi gerekir. Oluşturduğunuz bir şeyi "geri almak" silmektir. Zaten var olan bir şeyi "geri almak" ise geri yüklemektir. Bunları aynı şekilde ele almak, bir güvenlik mekanizmasının çalışan bir uygulamayı silmesinin yoludur.
- Hareket etmeden önce nasıl geri alınacağını yaz. Geri alma bilgisi yalnızca bir adım başarılı olduktan sonra kaydediliyorsa, yarıda başarısız olan bir adım geri almak için hiçbir şey bırakmaz.
- Bağlı olduğunuz bir isteğin yanıtını asla yok saymayın. Yok sayılan tek bir "hayır", sağlıklı bir uygulamayı başarısız bir yayına dönüştürdü.
Aynı günden ilgili bir düzeltme: açılıştan hemen sonra çöken uygulamaları yakalamak. Yayınınız tarafınızda başarısız olduğunda ne olacağı için, dokümantasyondaki yayın sorun giderme bölümüne bakın.