Saat 2’deki zihinsel çöküşün anatomisi
(zarar.dev)- jumpcomedy.com'da gece 10 civarında RTK Query’nin HTTP POST çağrıları tamamen başarısız olmaya başladı ve sitenin işlevleri bozuldu; yerelde ise normal çalıştığı için kök nedeni izlemek zordu
- Müşteri şikayetleri birikirken işletmeci, prodüksiyon destek, SRE, kıdemli mühendis veya yönetici olmadan kesintiyi tek başına göğüslemek zorunda kaldı
- Tarayıcıdaki
fetchile ilgili TypeError, GET ve DELETE’in normal çalıştığı durumla birleşince doğrudan bir ipucu sunmadı - Sentry, prodüksiyon DB’si, Cloudflare, Chrome güncellemeleri ve eski sürüme geri dönüşler kontrol edilse de hiçbir şey değişmedi; yerelde boş bırakılan PostHog api_key eklenince sorun yeniden üretildi
- PostHog kaldırıldıktan sonra işlevler normale döndü; ardından PostHog ve Redux Toolkit GitHub issue’larında aynı kesinti doğrulandı ve sorunun harici bir araçtan kaynaklandığı ortaya çıktı
Kesintinin yarattığı baskı
- jumpcomedy.com'da gece 10 civarından itibaren RTK Query tabanlı HTTP POST çağrıları tamamen başarısız olmaya başladı ve temel işlevler düzgün çalışmadı
- Yakın zamanda dağıtıma alınmış değişiklikler vardı ama bunlar doğrudan neden gibi görünmüyordu; ayrıca sorun yerel ortamda yeniden üretilemediği için iz sürmek daha da zorlaştı
- NextJS ve Vercel Discord kanallarından yardım istendi ancak yanıt alınamadı; kesinti müdahalesini devredecek bir prodüksiyon destek organizasyonu da yoktu
- Müşteri e-postaları gelmeye devam etti
- Etkinlik fiyatını değiştiremediklerine dair sorular
- Promosyon kodunu kaldıramadıklarına dair sorular
- Küçük işletme müşterilerinin hizmete bağımlı olması nedeniyle işletmeci utanç, üzüntü, yetersizlik ve imposter sendromu hissetti
Hata ayıklama süreci ve nedenin doğrulanması
- Tarayıcı hatası,
fetch’in daha önce kullanılmış bir request object ile çalıştırıldığına dair bir TypeError idi, ancak bu gerçek nedeni göstermedi - Çeşitli
console.log()çağrıları ve breakpoint’ler eklenerek header’lar, API token uzunluğu ve çağrı sırası kontrol edildi, fakat bunlar net bir nedene ulaşmayı sağlamadı - Chrome güncellemesi ihtimalinden şüphelenildi, ancak Firefox ve Edge’de de yeniden üretildiği için sorunun yalnızca tarayıcıya özgü olmadığı anlaşıldı
- Eski sürümlere dönüldüğünde de hata devam etti
- Bir ay önceki sürümde de başarısız oldu
- Üç ay önceki sürümde de başarısız oldu
- Bir yıl önceki sürümde de başarısız oldu
- Yerel ve prodüksiyon ortamı arasındaki farkı azaltmak için çeşitli adaylar kontrol edildi
- Prodüksiyonda Sentry kaldırıldı: değişiklik yok
- Yerel ortam prodüksiyon DB’sine bağlandı: değişiklik yok
- Cloudflare devre dışı bırakıldı: değişiklik yok
- Yerelde maliyeti azaltmak için PostHog api_key boş bırakılıyordu; bu anahtar eklenince aynı sorun yeniden üretildi
- Sonraki commit’te PostHog kaldırılınca tüm işlevler yeniden normal çalıştı
- Aynı sorun daha sonra GitHub issue’larında da doğrulandı
1 yorum
Hacker News görüşleri
Büyük bir küresel şirkette 1 yıl SRE olarak çalışırken, yazıda bahsedilen “panik” modundan çıkabildim.
İş tarafı açısından her sorun dünyanın sonuymuş gibi görünür ve o durumda paniğe kapılmak kolaydır; ama gerçekte durumun bu kadar kötü olduğu nadirdir, kötü olsa bile çoğu zaman sağ salim atlatılır.
Böyle durumlarda, hemen düzeltmeye girişmeden önce 5–10 dakika durup tabloyu olabildiğince net çizmeye çalışmak esastır. Korku, akılcı muhakemeyi engeller; panik hâlinde düğmelere rastgele basmak sorunu daha da içinden çıkılmaz hâle getirebilir. Benim taktiğim, korku devresini kırmak için yüzüme ve ellerime çok soğuk su çarpmak.
Bu tür şeyleri birkaç kez yaşadıktan sonra, durumun sandığınızdan daha yönetilebilir olduğunu; daha önce de kötü durumlarla başa çıktığınıza dair özgüven kazanıp yardım isteyecek kimse olmasa bile bunun üstesinden gelebileceğinizi anlıyorsunuz.
Satın alınan yazılımların kadrolama ya da yapılandırma hataları yüzünden hiçbir işe yaramaması, çalışanların kötü kullanıcı deneyimi ve anlamsız gereksinimler yüzünden her yıl binlerce saat kaybetmesi, hiçbir işlevi olmayan kabiliyetlerin atıl bırakılması, işe yaramaz toplantıların her gün zamanı boşa harcaması, denetim gereksinimlerini karşılamak için yalnızca var olan özelliklerin bulunması ya da yöneticilerin şirket parasını durmadan çarçur etmesi gibi şeyler.
Kesinti süresi bu sorunlardan daha kötü görünmüyor ama çok daha fazla ilgi ve panik çekiyor. Terörizm ile kalp hastalığı arasındaki tezat gibi hissettiriyor. Şirket sizin uykunuzu ya da ruh sağlığınızı umursamaz; sizi mümkün olduğunca zorlar. Bunun kötü niyetli olduğu anlamına gelmez ama bu konuda, siz geri çekildikçe daha da bastıran bir zorba gibidir.
Programlamadaki mottolarımdan biri “kara büyü yok”tur. Neden çalıştığını anlamıyorsan iş bitmiş sayılmaz.
Kesinti müdahalesine de aynı gözle bakıyorum. Birinin önerisinin neden etki edeceğini tutarlı biçimde açıklayamıyorsanız, bence onu uygulamamalısınız. Bir gün sadece tetiği çekmeniz gereken bir an gelebilir ama geriye dönüp baktığımda, sonunda böyle bir durum hiç yaşanmamış gibi geliyor.
Normalde son derece sakin olan üst düzey yöneticilerin, kesinti sırasında rastgele düzeltme adayları ortaya atmaya başladığını görmek epey sarsıcıydı.
Birileri bu tek kişilik geliştiriciyi “fetch’i yaygınlaştırmaya çalışma” diye durdursaydı zararın ne kadar daha büyük olacağını hayal edin.
Korkunun akılcı muhakemeyi engellediği doğru; buna, korkunun çok bulaşıcı olduğunu da eklemek isterim. Uygulayıcılar liderlerinin, yöneticilerinin ya da çalışma arkadaşlarının paniğe kapıldığını gördüğünde çoğu zaman onlar da paniğe kapılır. Neyse ki benim VP’m her zaman sakindi ve eylemden önce netliği önceliklendirdi.
Bunun zihinsel çöküş olup olmadığından pek emin değilim; teknik stres yüzünden gerçekten çöküş yaşayan insanlara yanlış bir izlenim de verebilir.
Benim başıma yalnızca bir kez geldi ve o da anksiyete atağıydı. Eşim yanımdaydı, durumu bana açıkladı ve ne yaşadığımı anlamama yardımcı oldu; bu açıdan gerçekten şanslıydım. Eşim bunu birkaç kez yaşamıştı ama benim için ilk ve neyse ki sondu.
Böyle şeyler insanların başına gelebilir ve bunun kendisi yanlış bir şey değildir. Kusurlu ya da zayıf olduğunuz anlamına gelmediğini içselleştirmek gerçekten önemlidir.
Benim durumumda bunu sonunda durduran şey Xanax oldu; uyuyabildiğim için el altında bulundurmanın değerli olduğunu düşünüyorum.
Söylemek istediğim, istem dışı düşünceler ile anksiyete atağı ya da panik atak gibi gerçekten kontrol edilemeyen ve işlev görmeyi felç eden durumların farklı olduğudur. Böyle bir şey olursa çalışamaz hâle gelirsiniz ve bu da sorun değil.
Her çöküş panik ya da anksiyete atağı şeklinde gelmez. Böyle ortaya çıkabilir ama tek yolu bu değildir. Stres, kişiden kişiye, hatta stres etkeninden stres etkenine çok farklı biçimlerde kendini gösterir.
O kişinin zihninde gerçekte ne yaşandığını bilemeyeceğimiz için dışarıdan “teşhis” koymak neredeyse imkânsızdır. Tam anlamıyla bir panik atak olmasa bile, birkaç saat boyunca işlevsel olarak felç olmuş gibi görünüyor.
İnternette bakınca Xanax’ın bağımlılık yapıcı olabileceği görülüyor.
https://www.drugs.com/xanax.html
Hafife alınıp kullanılacak türden bir şey gibi durmuyor.
2000’lerin ortasında teknoloji sektörüne giren büyük bir grubun stresle ilişkili hastalıklardan öldüğünü görme ihtimalimiz yüksek.
Hayat boyu yoğun anksiyete yaşamış biri olarak, bağımlılık yapabilen tek bir hapın bunların hepsini ortadan kaldırabileceği fikri bile korkutucu. Sanırım ona ömür boyu tutunup kalırdım.
Bu kişinin stresi PostHog’daki tek bir kod satırından kaynaklanmış. Geri alınan commit şu: https://github.com/PostHog/posthog-js/pull/1371/commits/7598...
Burada iki ders görüyorum. Birincisi, yayımladıysanız sahibi sizsiniz. Bu yüzden ne kadar az yayımlarsanız o kadar iyi; bağımlılıkları da en aza indirmek gerekir. İkincisi, önemli olmayan şeyleri kritik yolun dışında tutmalısınız. Klima kompresörü bozuldu diye motor durmamalı. Tarayıcıda bunu başarmak çok zor ama denemeye değer.
Daha da kötüsü, PostHog kendi kodunun bir kısmını çalışma zamanında dinamik olarak güncelliyor gibi görünüyor; build sırasında paketlemiyor gibi
Dokümantasyonda tüm bağımlılıkları build’e dahil eden gelişmiş bir seçenek var. Bunu neden yaptıklarını anlıyorum ve ben yanlış anlamış da olabilirim; ama kullanıcı açısından çalıştırılacak kodun gecikmeli yüklenmesinin varsayılan değil, bir optimizasyon seçeneği olmasını beklerim. Bence yalnızca tam paketleme ciddi teslim gecikmeleri yarattığında kullanılmalı
Hata, monkey-patch uygulanmış
window.fetchiçinde gibi görünüyorduhttps://github.com/PostHog/posthog-js/blob/759829c67fcb8720f...
Buradaki en büyük ders şu: Popüler bir kütüphane geliştirirken global fonksiyonlara monkey-patch uyguluyorsanız testleriniz gerçekten çok iyi olmalı
“Ne olur ne olmaz PostHog çağrılarını try/catch içine alalım” ile “PostHog yüzünden kelimenin tam anlamıyla
fetch()ile POST isteği gönderemiyoruz” tamamen farklı şeylerfetchin kullanılabileceği farklı biçimler için test kapsamı yetersiz, ayrıca aşırı mock kullanımı da pay sahibi gibi: https://github.com/PostHog/posthog-js/blob/main/src/_tests...fetch ve XHR fonksiyonlarının tamamı mock’lanıp hiçbir şey yapmaz hâle getirildiği için, doğal olarak alttaki native katmanla veya başka kütüphanelerle etkileşimden doğan sorunları yakalayamıyor. Cypress de ayarlı; tarayıcı API’lerini neden mock’lamak istediklerini anlamıyorum
Makul biçimde entegre edildiyse en kötü durumda bile yalnızca izleme olaylarının işlenmesi başarısız olur diye düşünmüştüm
PostHog’un çok önemli global fonksiyonları patch’lediği iyi belgelenmesi gereken bir özellik. Böylece kullananlar bunu bilir ve dışarıdan açıklaması zor görünen sorunları debug ederken makul biçimde akıllarında tutabilir
Örneğin Heap Analytics, bu ay itibarıyla hâlâ Hotwire’ın içinde bir şeylere dokunup Hotwire’ı rastgele tamamen bozuyor ve tüm tıklamaların tam sayfa yüklemesine dönüşmesine neden oluyor. Benim deneyimime göre sayfa yüklemelerinin %30–60’ını etkiliyor. Düzeltilebiliyor ama Heap’in tüm Hotwire JavaScript’lerinden sonra yüklenecek hâle getirilmesi için 50 saatten fazla debug yapmam gerekti
Başkalarının da söylediği gibi, bu gece yarısı stresine yol açan hata PostHog kütüphanesinde yapılan tek satırlık bir değişiklikti[0]
Ben bunu değişkenlere doğru adlar vermenin önemini hatırlatan bir olay olarak görüyorum
res = await originalFetch(url, init)kodu yeterince masum görünüyor. Ama TypeScript bildiriminin gösterdiği gibiurlparametresi mutlaka URL değil:url: URL | RequestInfoURL değil de bir RequestInfo nesnesi olduğunda sorun çıkıyor. Çünkü fonksiyon implementasyonunun başında bir Request nesnesi oluşturulurken zaten “tüketilmiş” oluyor ve burada tekrar kullanılamıyor
Parametre adı
urlOrRequestInfogibi daha doğru olsaydı bu değişiklikte sorunu gözden kaçırmak daha zor olurduÇok daha spekülatif bir düşünce ama lineer mantıktan gelen lineer tipler bir değerin “tüketildiğini” biçimselleştirebildiği için, uygun bir tip sistemi bu tür hataları da engelleyebilir gibi
[0] https://github.com/PostHog/posthog-js/pull/1351/commits/2497...
Rust gibi dillerdeki sahiplik semantiğine bakmak yeterli. Aşılamaz düzeyde değil ve özellikle deneyim kazandıkça kolaylaşıyor, ama öğrenenlerin en çok şikâyet ettiği noktalardan biri olacak kadar ağır
Stresli ama aynı zamanda komik bir yazıydı. Yine de kendini suçlama kısmı fazlasıyla tanıdık geldi
Oldukça başarılı bir iOS/macOS uygulaması işletiyorum; bir keresinde bir release’i yayına alıp 350 binden fazla kurulu kopyayı tamamen bozmuştum. Tamamen benim hatam değildi ama ürün benim olduğundan pek fark etmiyordu
O zamanki soğuk ter ve utanç gerçekten ağırdı. Üstelik App Store olduğu için düzeltme de inceleme sürecinden geçmek zorundaydı, bu da süreyi uzatıyordu. Neyse ki gönderdikten 30 dakika sonra incelemeye alındı ve birkaç dakika içinde onaylandı
Kariyerimde ilerleyip liderliğe geçince bunun çok değerli bir deneyim olduğunu fark ettim. Eskiden stres olmuş olabilirim ama şimdi o anı o kadar uzak ki bana dokunmuyor bile. Şu an kesinlikle stres olmuyorum
Tartışmalı olabilir ama bazen kariyerinin başındaki bir ekip üyesinin production ortamını bozmasına izin veriyorum. Önceden görebildiğimiz ve hızlıca toparlayabileceğimizden emin olduğumuz durumlarda
Hata yapabilecek alan vermenin önemli olduğu malum, ama birçok lider gerçek müşterileri etkileyen hatalarda çizgi çekiyor. Uçak indiren yazılım gibi kritik bir şey geliştirmediğiniz çok yaygın ve şanslı bir durumdaysanız, Washington eyaletinin Spokane kentindeki birinin ürünü birkaç dakika kullanamaması pahasına bile ekibin production kesintisi deneyimlemesini sağlamalısınız
Böyle bir yazı yazdığın için teşekkürler. Özellikle baskı altındayken, genelde gece boyunca, insanların bu tür zorlukları nasıl aştığını okumayı seviyorum
Yalnızca teknik bir postmortem değil, bu tür hikâyelerden genellikle silinen insani bakış açısını da duyabildiğim için daha iyi hissettirdi. Bu tür teknik anlatılar, ancak küçük ölçekli/tek kişilik geliştiricilerin ya da kurucuların özgürce paylaşabileceği türden
Sorunu izleme biçimine bakınca bile önce programcı olduğu görülüyor. Kendi koduna gitmiş, loglara gitmiş. İkisi de makul ve ikisi de neden olabilir; ama elindeki en önemli ipucu olan “localhost’ta çalışıyordu” noktasını kaçırmış
SRE, DevOps, platform mühendisi ya da o gün hangi unvan yapıştırılıyorsa, ben çalışan sistem ile çalışmayan sistem arasındaki farka odaklanırdım. Farkları tek tek ekleyip çıkararak ya da çıkarıp yeniden ekleyerek bir şey çalışana kadar bakardım
Benim gördüğüm iki şey var. 1) Çalışan bir ortam var. 2) Başarısız olan ortam da aslında çalışıyordu, sonra başarısız olmaya başladı
Bu, benim yöntemimin daha üstün olduğu anlamına gelmiyor. Sadece probleme bakış biçimindeki farkı göstermek istiyorum. İkisi de bildiği şeyler etrafında alanı daraltıyor. Ben sistemi biliyorum, siz kodu biliyorsunuz
Ben bunun umutsuz olduğunu düşünmüştüm, ama daha yaşlı ve bilge bir teknisyen bana yöntemi öğretti
Sağlam kartı extender’a takıp başarısız olan tanı programını döngüde çalıştırıyorduk. Osiloskopla konnektördeki tüm pinlere bakıp kaydediyorduk. Bozuk kartla değiştirip tekrarlıyorduk
Hangi sinyal farklı? O sinyali geriye doğru takip ediyorduk. Şema doğru değilse voltmetre ve gözle, gerçek kablolamayı yansıtan bir şema çiziyorduk
O buna “iyi kart - kötü kart” diyordu ve gerçekten işe yarıyordu. Maliyet açısından verimli olduğunu iddia etmem ama tüm kartları tamir ettik ve dijital elektronik devre sorunlarını giderme becerim ciddi ölçüde gelişti
Bu bir tür “itfaiyecilik” gibiydi. Sistemin bozulmasını beklemekti; bu yüzden 2 teknisyenin bir devre kartına 1 hafta harcaması sorun değildi
“Bir ay önceki sürüme geri dönelim. Olmadı. Üç ay öncesi? Olmadı. Hâlâ başarısız. Bir yıl öncesi? Hiç olmadı.”
Sadece kendi kodunu geri alıp, aynı gün bozulan PostHog güncellemesini kullanmaya devam mı ediyordu? Benim çıkardığım ders, bağımlılıklar dahil her şeyi geri alabilir hâle getirmek gerektiği
https://github.com/PostHog/posthog/issues/24471#issuecomment...
Doğrudan bundle’a dahil etme seçeneği de var
https://github.com/PostHog/posthog/issues/24471#issuecomment...
Orijinal yazının yazarı bunu iyi ele almış. Bu tür kesintilerin olumlu tarafı, değerli derslerin bolca çıkması
Servislerin arkasındaki insanları yeniden hatırlatan iyi bir yazı; hata ayıklama sürecini de iyi gösteriyor
Gerçekçi olmak gerekirse baskı, sorunu daha hızlı debug etmeyi sağlamaz. Genellikle düşünmeyi engeller. Sonuçları olabildiğince görmezden gelip mümkün olduğunca sakin kalmak gerekir
Çoğumuz az ya da çok benzer durumlar yaşamışızdır. Elbette kendi şirketini yönetmenin stresi özellikle büyük olur