Hata koşullarını nasıl yeniden üretiyor ve uygulama yürütülürken neler olduğunu nasıl görüyorsunuz?
Uygulamanın farklı eşzamanlı kısımları arasındaki etkileşimi nasıl görselleştirirsiniz?
Tecrübelerime dayanarak, bu iki yönün cevabı şöyledir:
Dağıtılmış izleme
Dağıtılmış izleme, sisteminizin her bir eşzamanlı bileşeni için zamanlama verilerini yakalayan ve grafiksel olarak size sunan bir teknolojidir. Eşzamanlı uygulamaların temsilleri her zaman bir araya getirilir, bu da neyin paralel çalıştığını ve neyin paralel olmadığını görmenizi sağlar.
Dağıtılmış izleme, kökenlerini (elbette) tanım gereği asenkron ve çok eş zamanlı olan dağıtılmış sistemlerde borçludur. Dağıtılmış izlemeli dağıtık bir sistem, insanların şunları yapmasını sağlar:
a) önemli darboğazları tespit etmek, b) başvurunuzun ideal “çalıştırmalarının” görsel bir temsilini almak ve c) eşzamanlı davranışların yürütülmesine görünürlük sağlamak, d) uygulamanızdaki değişiklikler arasındaki farkları değerlendirmek için kullanılabilecek zamanlama verilerini elde etmek Sistem (güçlü SLA'larınız varsa çok önemlidir).
Bununla birlikte, dağıtılmış izlemenin sonuçları şunlardır:
Potansiyel olarak bir ağ üzerinden yürütmek ve göndermek için daha fazla koda dönüştürdüğü için tüm eşzamanlı işlemlerinize ek yük ekler. Bazı durumlarda, bu ek yük çok önemlidir - Google bile, kullanıcı deneyimini mahvetmemek için sadece kendi istek sistemlerini Dapper'ı tüm isteklerin küçük bir alt kümesinde kullanır.
Hepsi birbiriyle birlikte çalışamayan pek çok farklı araç var. Bu, OpenTracing gibi standartlarla biraz iyileştirildi, ancak tamamen çözülmedi.
Size paylaşılan kaynaklar ve mevcut durumları hakkında hiçbir şey söylemez . Uygulama kodunu ve gördüğünüz grafiğin size ne gösterdiğini temel alarak tahmin edebilirsiniz, ancak bu konuda kullanışlı bir araç değildir.
Mevcut araçlar, yedeklenecek hafızanız ve deponuz olduğunu varsayar. Bir zaman sunucusunu barındırmak, kısıtlamalarınıza bağlı olarak ucuz olmayabilir.
Hata izleme yazılımı
Öncelikle orada Sentry ile bağlantı kurdum, çünkü orada en yaygın kullanılan araçtı ve iyi bir nedenden dolayı - Sentry kaçırma çalışma zamanı yürütme gibi hata izleme yazılımı aynı anda merkezi bir sunucuda karşılaşılan hataların yığın izini iletmek için.
Bu tür özel yazılımların eşzamanlı koddaki net faydası:
- Yinelenen hatalar çoğaltılmaz . Bir veya daha fazla eşzamanlı sistemlerinin aynı durum karşılaşırsanız Başka bir deyişle, Nöbetçi olacaktır artırır Bir olay raporu, ancak olayın iki kopyasını göndermeyin.
Bu, sayısız eşzamanlı hata raporundan geçmek zorunda kalmadan hangi eşzamanlı sistemin hangi hatayı yaşadığını anlayabilmeniz anlamına gelir. Dağıtılmış bir sistemden herhangi bir e-posta spamı yaşadıysanız, neye benzediğini biliyorsunuz.
Eşzamanlı sisteminizin farklı yönlerini bile 'etiketleyebilirsiniz' (bu, tam olarak tek bir iş parçacığı üzerinde işin bir araya gelmediğini varsayar; bu, teknik olarak zaten eşzamanlı olmayan bir iş olmadığı için, iş parçacığı sadece işler arasında verimli bir şekilde zıplar, ancak yine de olay işleyicileri işlemek zorundadır) tamamlamak için) ve hataların etikete göre dağılımını görün.
- Çalışma zamanı istisnalarınızla ilgili daha fazla ayrıntı sağlamak için bu hata işleme yazılımını değiştirebilirsiniz. Sürecin hangi açık kaynakları vardı? Bu sürecin tuttuğu ortak bir kaynak var mı? Hangi kullanıcı bu sorunu yaşadı?
Bu, titiz yığın izlerine ek olarak (ve dosyalarınızın küçültülmüş bir sürümünü sağlamanız gerekiyorsa kaynak haritaları), zamanın büyük bir kısmının neyin yanlış gittiğini belirlemenizi kolaylaştırır.
- (Sentry'e özel) Sistemin test çalışmaları için testte hatalar yakalamanıza izin veren ayrı bir Sentry raporlama panosu olabilir.
Bu gibi yazılımların dezavantajları:
Her şey gibi, toplu olarak eklerler. Örneğin gömülü donanımda böyle bir sistemi istemeyebilirsiniz. Bu tür bir yazılım denemesi yapmayı ve boşta çalışan bir makinede birkaç yüzün üzerinde çalışmayı örnekleyen ve olmayan basit bir yürütmeyi karşılaştırarak tavsiye ederim.
Tüm diller eşit olarak desteklenmemektedir, çünkü bu sistemlerin birçoğu örtük olarak bir istisna yakalamaya dayanmaktadır ve tüm diller sağlam istisnalar içermemektedir. Olduğu söyleniyor, çok sayıda sistem için müşteri var.
Bu sistemlerin çoğu temelde kapalı kaynaklı olduğundan, bir güvenlik riski olarak ortaya çıkabilir. Bu gibi durumlarda, onları araştırma konusundaki özeninizi yapın ya da tercih edilirse kendinizinkini kullanın.
Size her zaman ihtiyacınız olan bilgiyi vermeyebilirler. Bu, görünürlük eklemek için tüm girişimlerde bir risktir.
Bu hizmetlerin çoğu yüksek eşzamanlı web uygulamaları için tasarlanmıştır, bu nedenle her araç kullanım durumunuz için mükemmel olmayabilir.
Özetle : Görünürlük sahibi olmak, herhangi bir eşzamanlı sistemin en önemli kısmıdır. Yukarıda tarif ettiğim iki yöntem, herhangi bir zaman noktasında sistemin güncel bir görüntüsünü elde etmek için donanım ve veriler hakkındaki özel panolarla birlikte, sektörde tam olarak bu yönü ele almak için yaygın olarak kullanılmaktadır.
Bazı ek öneriler
Eşzamanlı sorunları korkunç yollarla çözmeye çalışan insanlar tarafından kod düzeltmeyi umduğumdan daha fazla zaman geçirdim. Her seferinde, aşağıdakilerin geliştirici deneyimini (kullanıcı deneyimi kadar önemlidir) büyük ölçüde geliştirebileceği durumlar buldum:
Türlerine güveniyor . Yazma, kodunuzu doğrulamak için mevcuttur ve çalışma zamanında ekstra bir koruma olarak kullanılabilir. Yazmanın bulunmadığı yerlerde, hataları yakalamak için iddialara ve uygun bir hata işleyicisine güvenin. Eşzamanlı kod , savunma kodu gerektirir ve türler, mevcut en iyi doğrulama türü olarak görev yapar.
- Yalnızca bileşenin kendisini değil, kod bileşenleri arasındaki bağlantıları test edin. Bunu, her bileşen arasındaki her bağlantıyı test eden tam gelişmiş bir entegrasyon testiyle karıştırmayın ve o zaman bile, yalnızca nihai durumun küresel bir onayını arar. Bu, hataları yakalamanın korkunç bir yoludur.
İyi bir bağlantı testi , bir bileşen yalıtılmış bir başka bileşenle konuştuğunda , mesajın ve gönderilen mesajın beklediğinizle aynı olup olmadığını kontrol eder. İletişim kurmak için paylaşılan bir servise dayanan iki veya daha fazla bileşeniniz varsa, hepsini toplayın, merkezi servis aracılığıyla mesaj alışverişinde bulunun ve en sonunda ne beklediğinizi alıp almadıklarını görün.
Bileşenlerin kendilerinin bir testine birçok bileşenin dahil olduğu ayrılma testleri ve bileşenlerin her birinin nasıl iletişim kurduğunun bir testi de kodunuzun geçerliliğine olan güveninizi arttırır. Böylesine titiz bir test kitlesine sahip olmak, hizmetler arasında sözleşmeleri uygulamanıza ve aynı anda çalışırken ortaya çıkan beklenmeyen hataları yakalamanıza izin verir.
- Uygulama durumunuzu doğrulamak için doğru algoritmaları kullanın. Örneğin, tüm çalışanlarının bir işi bitirmesini bekleyen bir ana süreciniz olduğunda ve sadece tüm çalışanlar tamamen yapılırsa bir sonraki adıma geçmek istediğiniz gibi, basit şeylerden bahsediyorum. Safra algoritması gibi bilinen metodolojilerin bulunduğu fesih.
Bu araçlardan bazıları, dillerle birlikte gelir - Rust, örneğin, kodunuzun derleme zamanında herhangi bir yarış koşuluna sahip olmayacağını garanti ederken, Go, derleme zamanında çalışan dahili bir kilitlenme algılayıcısına sahiptir. Üretime başlamadan önce sorunları yakalarsanız, bu her zaman bir kazançtır.
Genel bir kural: eşzamanlı sistemlerde başarısızlık için tasarım . Ortak hizmetlerin çökeceğini veya kırılacağını tahmin edin. Bu, makinelere dağıtılmayan kodlar için bile geçerlidir - tek bir makinedeki eşzamanlı kod, herhangi bir zamanda kaybolabilecek veya kaldırılabilecek harici bağımlılıklara (paylaşılan bir günlük dosyası, Redis sunucusu, lanet bir MySQL sunucusu gibi) güvenebilir .
Bunu yapmanın en iyi yolu zaman zaman uygulama durumunu doğrulamaktır - her hizmet için sağlık kontrolleri yaptırmak ve bu hizmetten tüketicilerin sağlık durumunun kötü şekilde bildirildiğinden emin olmak. Docker gibi modern konteyner araçları bunu oldukça iyi yapıyor ve işleri sanallaştırmak için kullanılmalı.
Neyin eşzamanlı yapılabileceğini ve neyin sırayla yapılabileceğini nasıl anlarsınız?
Çok eş zamanlı bir sistemde çalışmayı öğrendiğim en büyük derslerden biri şudur: Asla yeterince ölçüm alamazsınız . Metrikler uygulamanızdaki her şeyi kesinlikle kullanmalıdır - her şeyi ölçemiyorsanız bir mühendis değilsiniz.
Metrikler olmadan, birkaç önemli şey yapamazsınız:
Sistemdeki değişikliklerle yapılan farkı değerlendirin. Ayar A düğmesinin metrik B'nin yukarı çıkıp metrik C'nin aşağı inip girmediğini bilmiyorsanız, insanlar sisteminizde beklenmedik bir şekilde kötü niyetli kodlar bastığında sisteminizi nasıl düzelteceğinizi bilmiyorsunuz (ve sisteminize kodu itecekler) .
İşleri geliştirmek için yapmanız gerekenleri anlayın. Uygulamaların belleğinin azaldığını öğrenene kadar, sunucularınız için daha fazla bellek mi yoksa daha fazla disk mi almanız gerektiğini ayırt edemezsiniz.
Metrikler o kadar önemli ve önemlidir ki, bir sistemin neye ihtiyaç duyacağını bile düşünmeden önce neyi ölçmek istediğimi planlamak için bilinçli bir çaba gösterdim. Aslında, metrikler o kadar önemlidir ki , bu sorunun doğru cevabı olduklarına inanıyorum : programınızdaki bitlerin ne yaptığını ölçtüğünüzde sadece sıralı veya eşzamanlı yapılabilecek şeyleri bilirsiniz . Doğru tasarım, tahminde değil sayıları kullanır.
Olduğu söyleniyor, kesinlikle birkaç kural vardır:
Sıralı bağımlılığı ifade eder. Biri diğerine bağımlıysa, iki işlem sıralı olmalıdır. Bağımlılığı olmayan süreçler eşzamanlı olmalıdır. Bununla birlikte, aşağı akıştaki süreçlerin süresiz olarak beklemelerini engellemeyen arıza akışını ele almanın bir yolunu planlayın.
Bir G / Ç bağımlı görevini hiçbir zaman aynı çekirdekteki CPU bağlı bir görevle karıştırmayın. (Örneğin), aynı iş parçacığında on eşzamanlı istek başlatan, geldikleri anda bunları kazıyan ve beş yüze kadar ölçeklenmeyi bekleyen bir web tarayıcısı yazmayın; CPU hala seri olarak geçecek. (Bu tek iş parçacıklı olay odaklı model popüler bir modeldir, ancak bu yönü nedeniyle sınırlıdır - bunu anlamak yerine insanlar sadece ellerini sıkıyorlar ve Düğüm'ün ölçeklemediğini söylüyorlar, size bir örnek vermek için).
Tek bir diş çok fazla G / Ç çalışması yapabilir. Ancak, donanımınızın eşzamanlılığını tam olarak kullanmak için, birlikte tüm çekirdeği dolduran iş parçacıkları kullanın. Yukarıdaki örnekte, sadece CPU çalışması için beş Python işleminin (her biri altı çekirdekli bir makinede bir çekirdek kullanabilen) başlatılması ve sadece I / O çalışması için altıncı bir Python iş parçacığının düşündüğünüzden çok daha hızlı ölçeklendirilmesi.
CPU eşzamanlılığından faydalanmanın tek yolu özel bir threadpool. Tek bir iş parçacığı çoğu zaman G / Ç'ye bağlı iş için yeterince iyidir. Bu nedenle Nginx gibi olaya dayalı web sunucularının Apache'ye göre daha iyi ölçeklendirmelerine (tamamen G / Ç'ye bağlı işleri yapmalarına) neden olurlar (bu, G / Ç'ye bağlı işleri CPU gerektiren bir şeyle işler ve istek başına bir işlem başlatır), ancak neden Node'u gerçekleştirmek için Paralel olarak alınan onbinlerce GPU hesaplaması korkunç bir fikir.