Braze, Ruby'yi Ölçekte Nasıl Kullanıyor?

Yayınlanan: 2022-08-18

Hacker Haberlerini, Geliştirici Twitter'ı veya oradaki diğer benzer bilgi kaynaklarını okuyan bir mühendisseniz, “Pas'ın Hızı ve C”, “Düğüm Ne Yapar. js Java'dan Daha Hızlı mı?" veya "Neden Golang Kullanmalısınız ve Nasıl Başlamalı?" Bu makaleler genellikle, ölçeklenebilirlik veya hız için bariz bir seçim olan belirli bir dil olduğunu ve sizin yapmanız gereken tek şeyin onu benimsemek olduğunu öne sürer.

Üniversitedeyken ve mühendis olarak ilk veya iki yılımda bu makaleleri okur ve yeni dili veya çerçeve du jour'u öğrenmek için hemen bir evcil hayvan projesi başlatırdım. Ne de olsa “küresel ölçekte” ve “şimdiye kadar gördüğünüz her şeyden daha hızlı” çalışması garanti edildi ve buna kim karşı koyabilir? Sonunda, projelerimin çoğu için bu çok özel şeylerden hiçbirine ihtiyacım olmadığını anladım. Ve kariyerim ilerledikçe, hiçbir dil veya çerçeve seçiminin bana bunları bedavaya vermeyeceğini fark ettim.

Bunun yerine, sistemleri ölçeklendirmek istediğinizde dilleri veya çerçeveleri değil, mimarinin aslında en büyük kaldıraç olduğunu keşfettim.

Braze'de muazzam bir küresel ölçekte faaliyet gösteriyoruz. Ve evet, bunu yapmak için birincil araçlarımızdan ikisi olarak Ruby ve Rails kullanıyoruz. Ancak, tüm bunları mümkün kılan bir "global_scale = true" yapılandırma değeri yoktur; bu, uygulamaların derinliklerine ve dağıtım topolojilerine kadar uzanan iyi düşünülmüş bir mimarinin sonucudur. Braze'deki mühendisler sürekli olarak ölçekleme darboğazlarını inceliyor ve sistemimizi nasıl daha hızlı hale getireceğimizi bulmaya çalışıyor ve cevap genellikle “Ruby'den uzaklaşmak” değil: Neredeyse kesinlikle mimaride bir değişiklik olacak.

Öyleyse, Braze'in hız ve devasa bir küresel ölçeği gerçekten çözmek için düşünceli mimariden nasıl yararlandığına ve Ruby ve Rails'in nereye uyduğuna (ve uymayacağına) bir göz atalım!

Sınıfının En İyisi Mimarinin Gücü

Basit Bir Web İsteği

Çalıştığımız ölçek nedeniyle, müşterilerimizin kullanıcı tabanlarıyla ilişkili cihazların her gün bir Braze web sunucusu tarafından sunulması gereken milyarlarca web isteği yapacağını biliyoruz. Ve en basit web sitelerinde bile, bir istemciden sunucuya ve geri gelen bir istekle ilişkili nispeten karmaşık bir akışa sahip olacaksınız:

  1. Bu, müşterinin DNS çözümleyicisinin (genellikle onların ISS'si) web sitenizin URL'sindeki etki alanına göre hangi IP adresine gidileceğini bulması ile başlar.

  2. İstemcinin bir IP adresi olduğunda, isteği ağ geçidi yönlendiricisine gönderir, bu da istek hedef IP adresine ulaşana kadar "sonraki atlama" yönlendiricisine (birkaç kez olabilir) gönderir.

  3. Oradan, isteği alan sunucudaki işletim sistemi ağ ayrıntılarını işleyecek ve web sunucusunun bekleme sürecine, dinlediği soket/portta gelen bir isteğin alındığını bildirecektir.

  4. Web sunucusu yanıtı (istenen kaynak, belki bir index.html) bu sokete yazar, bu da yönlendiriciler aracılığıyla istemciye geri döner.

Basit bir web sitesi için oldukça karmaşık şeyler, değil mi? Neyse ki, bunların çoğu bizim için hallediliyor (bir saniye içinde bunun hakkında daha fazlası). Ancak sistemimizde hala veri depoları, arka plan işleri, eşzamanlılık endişeleri ve uğraşması gereken daha fazlası var! Bunun neye benzediğine dalalım.

Ölçeği Destekleyen İlk Sistemler

DNS ve ad sunucuları, çoğu durumda genellikle çok fazla dikkat gerektirmez. Üst Düzey Etki Alanı adı sunucunuz, muhtemelen “web siteniz.com”u etki alanınızın ad sunucularıyla eşlemek için birkaç girişe sahip olacaktır ve Amazon Route 53 veya Azure DNS gibi bir hizmet kullanıyorsanız, adı onlar halledecektir. alan adınız için sunucular (ör. A, CNAME veya diğer kayıt türlerini yönetme). Genellikle bu bölümü ölçeklendirmeyi düşünmeniz gerekmez, çünkü bu, kullandığınız sistemler tarafından otomatik olarak gerçekleştirilecektir.

Bununla birlikte, akışın yönlendirme kısmı ilginç olabilir. Önce En Kısa Yolu Aç veya Yönlendirme Bilgi Protokolü gibi birkaç farklı yönlendirme algoritması vardır ve bunların tümü istemciden sunucuya en hızlı/en kısa yolu bulmak için tasarlanmıştır. İnternet etkin bir şekilde birbirine bağlı dev bir grafik (veya alternatif olarak bir akış ağı) olduğu için, her biri daha yüksek veya daha düşük maliyetli olan, kullanılabilecek birden fazla yol olabilir. Mutlak en hızlı rotayı bulmak için çalışmak yasak olurdu, bu nedenle çoğu algoritma kabul edilebilir bir rota elde etmek için makul buluşsal yöntemler kullanır. Bilgisayarlar ve ağlar her zaman güvenilir değildir, bu nedenle müşterimizin sunucularımıza daha hızlı yönlendirme yeteneğini geliştirmek için Fastly'ye güveniyoruz.

Fastly, dünyanın her yerinde çok hızlı ve güvenilir bağlantılarla varlık noktaları (POP'lar) sağlayarak çalışır. Bunları internetin eyaletler arası otoyolu olarak düşünün. Alan adlarımızın A ve CNAME kayıtları Fastly'ye işaret ediyor ve bu da müşterilerimizin isteklerinin doğrudan otoyola gitmesine neden oluyor. Oradan Fastly onları doğru yere yönlendirebilir.

Braze için Ön Kapı

Pekala, müşterimizin isteği Fastly otoyoluna gitti ve Braze platformunun ön kapısına ulaştı - sonra ne olacak?

Basit bir durumda, bu ön kapı, istekleri kabul eden tek bir sunucu olacaktır. Tahmin edebileceğiniz gibi, bu çok iyi ölçeklenmez, bu yüzden aslında Fastly'yi bir dizi yük dengeleyiciye işaret ediyoruz. Yük dengeleyicilerin kullanabileceği her türlü strateji vardır, ancak bu senaryoda Fastly round-robins'in bir yük dengeleyici havuzuna eşit bir şekilde istekte bulunduğunu hayal edin. Bu yük dengeleyiciler, istekleri sıraya alır, ardından bu istekleri web sunucularına dağıtır; bu, istemci isteklerinin her seferinde bir kez tekrarlandığını da hayal edebiliyoruz. (Pratikte belirli türdeki yakınlıkların avantajları olabilir, ancak bu başka bir zamanın konusu.)

Bu, aldığımız isteklerin aktarım hızına ve işleyebileceğimiz isteklerin aktarım hızına bağlı olarak yük dengeleyicilerin ve web sunucularının sayısını artırmamıza olanak tanır. Şimdiye kadar, devasa bir talep saldırısını hiç terlemeden kaldırabilecek bir mimari inşa ettik! Yük dengeleyicilerin istek kuyruklarının esnekliği sayesinde ani trafik kalıplarının üstesinden bile gelebilir - ki bu harika!

Web Sunucuları

Son olarak, heyecan verici (Ruby) kısma geliyoruz: Web sunucusu. Ruby on Rails kullanıyoruz, ancak bu sadece bir web çerçevesidir—gerçek web sunucusu Unicorn'dur. Unicorn, her çalışan işleminin iş için bir işletim sistemi soketini dinlediği bir makinede bir dizi çalışan işlemi başlatarak çalışır. Bizim için süreç yönetimini gerçekleştirir ve isteklerin yük dengelemesini işletim sisteminin kendisine erteler. İstekleri olabildiğince hızlı işlemek için sadece Ruby kodumuza ihtiyacımız var; diğer her şey bizim için Ruby dışında etkin bir şekilde optimize edilmiştir.

SDK'mız tarafından müşterilerimizin uygulamaları içinde veya REST API'miz aracılığıyla yapılan isteklerin çoğu eşzamansız olduğundan (yani, müşterilere belirli bir yanıt döndürmek için işlemin tamamlanmasını beklememize gerek yoktur), API sunucuları olağanüstü basittir; isteğin yapısını, herhangi bir API anahtarı kısıtlamasını doğrular, ardından isteği bir Redis kuyruğuna atar ve her şey yolunda giderse istemciye 200 yanıtı döndürür.

Bu istek/yanıt döngüsü, Ruby kodunun işlenmesi için yaklaşık 10 milisaniye sürer ve bunun bir kısmı Memcached ve Redis'te beklemek için harcanır. Tüm bunları başka bir dilde yeniden yazacak olsak bile, bundan daha fazla performans elde etmemiz pek mümkün değil. Ve nihayetinde, müşterilerimizin sürekli artan ihtiyaçlarını karşılamak için bu veri alma sürecini ölçeklendirmemizi sağlayan şey, şu ana kadar okuduğunuz her şeyin mimarisidir.

İş Kuyrukları

Bu, geçmişte araştırdığımız bir konudur, bu nedenle bu konuya derinlemesine girmeyeceğim - iş kuyruğu sistemimiz hakkında daha fazla bilgi edinmek için Kuyruklarla Dayanıklılık Elde Etme başlıklı yazıma göz atın. Yüksek düzeyde yaptığımız şey, iş kuyrukları gibi davranan çok sayıda Redis örneğinden yararlanmak ve yapılması gereken işleri daha fazla arabelleğe almaktır. Web sunucularımıza benzer şekilde, bu örnekler belirli bir kullanılabilirlik bölgesinde bir sorun olması durumunda daha yüksek kullanılabilirlik sağlamak için kullanılabilirlik bölgelerine bölünür ve yedeklilik için Redis Sentinel kullanan birincil/ikincil çiftler halinde gelirler. Bunları hem kapasite hem de verim için optimize etmek için hem yatay hem de dikey olarak ölçeklendirebiliriz.

Çalışanlar

Bu kesinlikle en ilginç kısımdır - işçileri nasıl ölçeklendiririz?

Her şeyden önce, çalışanlarımız ve kuyruklarımız bir dizi boyuta göre bölümlere ayrılmıştır: Müşteriler, iş türleri, gereken veri depoları vb. Bu, yüksek kullanılabilirliğe sahip olmamızı sağlar; örneğin, belirli bir veri deposu zorluk yaşıyorsa, diğer işlevler kusursuz bir şekilde çalışmaya devam edecektir. Ayrıca, bu boyutlardan herhangi birine bağlı olarak çalışan türlerini bağımsız olarak otomatik olarak ölçeklendirmemize olanak tanır. Sonunda, işçi kapasitesini yatay olarak ölçeklenebilir bir şekilde yönetebiliyoruz - yani, belirli bir iş türünden daha fazlasına sahipsek, daha fazla işçiyi büyütebiliriz.

Dil veya çerçeve seçimi meselesini görmeye başlayabileceğiniz yer burasıdır. Sonuçta, daha verimli bir işçi daha fazla işi daha hızlı yapabilecektir. C veya Rust gibi derlenmiş diller, hesaplama görevlerinde Ruby gibi yorumlanmış dillerden çok daha hızlı olma eğilimindedir ve bu, bazı iş yükleri için daha verimli çalışanlara yol açabilir. Ancak, izleri incelemek için çok zaman harcıyorum ve Braze'deki büyük resimde ham CPU işleme şaşırtıcı derecede küçük bir miktar. İşleme zamanımızın çoğu, çarpışan sayılarla değil, veri depolarından veya harici isteklerden gelen yanıtları beklemekle geçer; Bunun için yoğun şekilde optimize edilmiş C koduna ihtiyacımız yok.

Veri Depoları

Şimdiye kadar, ele aldığımız her şey oldukça ölçeklenebilir. O halde bir dakikanızı ayıralım ve çalışanlarımızın zamanlarının çoğunu nerede harcadıkları hakkında konuşalım - veri depoları.

Web sunucularını veya SQL veritabanı kullanan eşzamansız çalışanları ölçeklendiren herkes, muhtemelen belirli bir ölçek sorunuyla karşılaşmıştır: İşlemler. İki Gönderim Talebi ve bir Ödeme Makbuzu oluşturan bir Siparişi tamamlamakla ilgilenen bir uç noktanız olabilir. Bunların hepsi bir işlemde olmazsa, tutarsız verilerle karşılaşabilirsiniz. Tek bir veritabanında aynı anda çok sayıda işlemin yürütülmesi, kilitlere ve hatta kilitlenmeye çok zaman harcanmasına neden olabilir. Braze'de, nesne bağımsızlığı ve nihai tutarlılık yoluyla bu ölçekleme sorununu veri modellerinin kendileriyle birlikte ele alıyoruz. Bu ilkelerle, veri depolarımızdan çok fazla performans elde edebiliriz.

Bağımsız Veri Nesneleri

MongoDB'yi Braze'de çok iyi nedenlerle yoğun bir şekilde kullanıyoruz: Yani, MongoDB parçalarını büyük ölçüde yatay olarak ölçeklendirmemizi ve depolama ve performansta doğrusala yakın artışlar elde etmemizi mümkün kılıyor. Bu, birbirinden bağımsız olmaları nedeniyle kullanıcı profillerimiz için çok iyi çalışır—kullanıcı profilleri arasında sürdürülmesi gereken JOIN ifadesi veya kısıtlama ilişkisi yoktur. Müşterilerimizin her biri büyüdükçe veya yeni müşteriler ekledikçe (veya her ikisini birden), kapasitemizi artırmak için mevcut veritabanlarına yeni veritabanları ve yeni parçalar ekleyebiliriz. Bu ölçeklenebilirlik düzeyini korumak için çok belgeli işlemler gibi özelliklerden açıkça kaçınıyoruz.

MongoDB'nin yanı sıra, analitik bilgilerinin arabelleğe alınması gibi şeyler için Redis'i genellikle geçici bir veri deposu olarak kullanırız. Bu analizlerin çoğu için doğruluk kaynağı bir süre için bağımsız belgeler olarak MongoDB'de bulunduğundan, arabellek görevi görecek yatay olarak ölçeklenebilir bir Redis örneği havuzunu koruyoruz; bu yaklaşım altında, karma belge kimliği, bağımsızlık nedeniyle yükü eşit olarak yayarak, anahtar tabanlı bir parçalama şemasında kullanılır. Periyodik işler, bu arabellekleri yatay olarak ölçeklenen bir veri deposundan yatay olarak ölçeklenen başka bir veri deposuna boşaltır. Ölçek elde edildi!

Ayrıca, yukarıda bahsedilen iş kuyrukları için yaptığımız gibi bu durumlar için de Redis Sentinel kullanıyoruz. Ayrıca, bu Redis kümelerinin çok sayıda "türünü" farklı amaçlar için dağıtır ve bize kontrollü bir arıza akışı sağlarız (yani, belirli bir Redis kümesi türünün sorunları varsa, alakasız özelliklerin aynı anda başarısız olmaya başladığını görmeyiz).

Nihai Tutarlılık

Braze ayrıca çoğu okuma işlemi için nihai tutarlılığı bir ilke olarak kullanır. Bu, çoğu durumda MongoDB replika kümelerinin hem birincil hem de ikincil üyelerinden okumadan yararlanmamızı sağlayarak mimarimizi daha verimli hale getirir. Veri modelimizdeki bu ilke, yığınımızın her yerinde önbelleğe almayı yoğun bir şekilde kullanmamıza olanak tanır.

Memcached kullanarak çok katmanlı bir yaklaşım kullanıyoruz—temelde, veritabanından bir belge talep ederken, önce çok düşük yaşama süresine (TTL) sahip bir makine yerel Memcached sürecini kontrol edeceğiz, ardından uzak bir Memcached örneğini kontrol edeceğiz (ile daha yüksek bir TTL), veritabanına doğrudan sormadan önce. Bu, müşteri ayarları veya kampanya ayrıntıları gibi yaygın belgeler için veritabanı okumalarını önemli ölçüde azaltmamıza yardımcı olur. “Nihai” korkutucu gelebilir, ancak gerçekte, sadece birkaç saniyedir ve bu yaklaşımı benimsemek, gerçeğin kaynağından gelen muazzam miktarda trafiği keser. Daha önce bir bilgisayar mimarisi dersi aldıysanız, bu yaklaşımın CPU'ların L1, L2 ve L3 önbellek sisteminin nasıl çalıştığına ne kadar benzer olduğunu fark edebilirsiniz!

Bu hilelerle, mimarimizin tartışmasız en yavaş kısmından çok fazla performans sıkıştırabilir ve daha sonra verim veya kapasite ihtiyaçlarımız arttığında uygun şekilde yatay olarak ölçeklendirebiliriz.

Ruby ve Rails'in Yer Aldığı Yer

Sorun şu: Her katmanın yatay olarak iyi ölçeklendiği bütünsel bir mimari oluşturmak için çok çaba harcadığınızda, dilin veya çalışma zamanının hızı düşündüğünüzden çok daha az önemli hale geliyor. Bu, dillerin, çerçevelerin ve çalışma zamanlarının seçimlerinin tamamen farklı gereksinimler ve kısıtlamalarla yapıldığı anlamına gelir.

Ruby ve Rails, Braze 2011'de başlatıldığında ekiplerin hızlı bir şekilde yineleme yapmasına yardımcı olma konusunda kanıtlanmış bir geçmişe sahipti ve bunu mümkün kılmaya devam ettiği için GitHub, Shopify ve diğer önde gelen markalar tarafından hala kullanılıyorlar. Sırasıyla Ruby ve Rails toplulukları tarafından aktif olarak geliştirilmeye devam ediyorlar ve her ikisinin de hala çeşitli ihtiyaçlar için harika bir açık kaynak kitaplığı seti var. Çift, hızlı yineleme için harika bir seçimdir, çünkü muazzam miktarda esnekliğe sahiptirler ve yaygın kullanım durumları için önemli miktarda basitlik sağlarlar. Bunu kullandığımız her gün ezici bir çoğunlukla doğru buluyoruz.

Bu, Ruby on Rails'in herkes için işe yarayacak mükemmel bir çözüm olduğu anlamına gelmiyor. Ancak Braze'de, hızlı yineleme gerektiren ve Braze'in başarısının merkezinde yer alan veri alma işlem hattımızın, mesaj gönderme hattımızın ve müşteriye yönelik panomuzun büyük bir kısmına güç sağlamak için çok iyi çalıştığını gördük. bir bütün olarak platform.

Ruby Kullanmadığımızda

Fakat bekle! Braze'de yaptığımız her şey Ruby'de değil. Yıllar boyunca, çeşitli nedenlerle işleri başka dillere ve teknolojilere yönlendirmek için çağrıda bulunduğumuz birkaç yer var. Ruby'ye ne zaman güvenip ne zaman güvenmediğimize dair ek bilgi sağlamak için üç tanesine bir göz atalım.

1. Gönderen Hizmetleri

Anlaşıldığı üzere, Ruby tek bir işlemde çok yüksek derecede eşzamanlı ağ isteklerini işleme konusunda pek iyi değil. Bu bir sorun çünkü Braze müşterilerimiz adına mesaj gönderirken bazı hat sonu servis sağlayıcıları kullanıcı başına bir istek gerektirebilir. Gönderilmeye hazır 100 mesaj yığınımız olduğunda, bir sonrakine geçmeden önce her birinin bitmesini beklemek istemiyoruz. Tüm bu işleri paralel olarak yapmayı tercih ederiz.

Golang'da yazılmış durum bilgisi olmayan mikro hizmetler olan "Gönderen Hizmetlerimizi" girin. Yukarıdaki örnekteki Ruby kodumuz, tüm istekleri paralel olarak yürütecek, bitmesini bekleyecek ve ardından Ruby'ye toplu bir yanıt döndürecek olan bu hizmetlerden birine 100 mesajın tamamını gönderebilir. Bu hizmetler, eş zamanlı ağ oluşturma söz konusu olduğunda, Ruby ile yapabileceklerimizden önemli ölçüde daha verimlidir.

2. Akım Konnektörleri

Braze Currents yüksek hacimli veri dışa aktarma özelliğimiz, Braze müşterilerinin birçok veri ortağımızdan bir veya daha fazlasına sürekli olarak veri akışı yapmasına olanak tanır. Platform, Apache Kafka tarafından desteklenmektedir ve akış, Kafka Bağlayıcıları aracılığıyla yapılır. Bunları teknik olarak Ruby'de yazabilirsiniz, ancak resmi olarak desteklenen yol Java'dır. Ve yüksek derecede Java desteği nedeniyle, bu bağlayıcıları yazmak Java'da Ruby'den çok daha kolaydır.

3. Makine Öğrenimi

Makine öğreniminde daha önce herhangi bir çalışma yaptıysanız, tercih ettiğiniz dilin Python olduğunu bilirsiniz. Python'daki makine öğrenimi iş yükleri için çok sayıda paket ve araç, eşdeğer Ruby desteğini gölgede bırakıyor; TensorFlow ve Jupyter not defterleri gibi şeyler ekibimiz için çok önemli ve bu tür araçlar Ruby dünyasında mevcut değil ya da yeterince yerleşik değil. Buna göre, makine öğreniminden yararlanan ürünümüzün öğelerini oluşturmaya gelince Python'a yöneldik.

Dil Önemli olduğunda

Açıkçası, yukarıda Ruby'nin ideal seçim olmadığı birkaç harika örneğimiz var. Farklı bir dil seçmeniz için pek çok neden var; burada özellikle dikkate almanın yararlı olduğunu düşündüğümüz birkaç tane var.

Maliyetleri Değiştirmeden Yeni Şeyler İnşa Etmek

Tamamen yeni bir sistem kuracaksanız, yeni bir etki alanı modeliyle ve mevcut işlevsellik ile sıkı bir şekilde bütünleşme olmadan, isterseniz farklı bir dil kullanma fırsatınız olabilir. Özellikle kuruluşunuzun farklı fırsatları değerlendirdiği durumlarda, daha küçük, izole bir sıfırdan alan projesi, yeni bir dil veya çerçeve denemek için gerçek dünyada harika bir deney olabilir.

Göreve Özgü Dil Ekosistemi ve Ergonomi

Bazı görevler belirli bir dil veya çerçeve ile çok daha kolaydır - özellikle pano işlevselliğinin geliştirilmesi için Rails ve Grape'i seviyoruz, ancak açık kaynak araçları mevcut olmadığı için makine öğrenimi kodu Ruby'de yazmak için mutlak bir kabus olacaktır. Bir tür işlevsellik veya entegrasyon uygulamak için belirli bir çerçeve veya kitaplık kullanmak isteyebilirsiniz ve bazen dil seçiminiz bundan etkilenecektir, çünkü neredeyse kesinlikle daha kolay veya daha hızlı bir geliştirme deneyimi ile sonuçlanacaktır.

Yürütme Hızı

Bazen, ham yürütme hızı için optimize etmeniz gerekir ve kullanılan dil bunu büyük ölçüde etkiler. Birçok yüksek frekanslı ticaret platformunun ve otonom sürüş sisteminin C++ ile yazılmasının iyi bir nedeni var; yerel olarak derlenmiş kod çılgınca hızlı olabilir! Gönderici Hizmetlerimiz, Golang'ın Ruby'de bu nedenle mevcut olmayan paralellik/eşzamanlılık ilkellerinden yararlanır.

Geliştirici Aşinalığı

Öte yandan, izole edilmiş bir şey inşa ediyor olabilirsiniz veya aklınızda kullanmak istediğiniz bir kitaplık olabilir, ancak dil seçiminiz ekibinizin geri kalanına tamamen yabancıdır. Scala'da işlevsel programlamaya yönelik yoğun bir yalınlıkla yeni bir proje başlatmak, ekibinizdeki diğer geliştiriciler için bir aşinalık engeli oluşturabilir, bu da sonuçta bilgi izolasyonu veya net hızın azalmasıyla sonuçlanabilir. Hızlı yinelemeye yoğun vurgu yaptığımız için Braze'de bunu özellikle önemli buluyoruz, bu nedenle kuruluşta zaten yaygın olarak kullanılan araçların, kitaplıkların, çerçevelerin ve dillerin kullanımını teşvik etme eğilimindeyiz.

Son düşünceler

Zamanda geriye gidip dev sistemlerdeki yazılım mühendisliği hakkında kendime bir şey söyleyebilseydim, bu şu olurdu: Çoğu iş yükü için, genel mimari seçimleriniz ölçekleme sınırlarınızı belirleyecek ve bir dil seçiminin yapabileceğinden çok daha hızlı olacaktır. Bu içgörü Braze'de her gün kanıtlanmıştır.

Ruby ve Rails, düzgün bir şekilde tasarlanmış bir sistemin parçası olduğunda inanılmaz derecede iyi ölçeklenen inanılmaz araçlardır. Rails aynı zamanda oldukça olgun bir çerçevedir ve Braze'deki gerçek müşteri değerini hızlı bir şekilde yineleme ve üretme kültürümüzü destekler. Bunlar, Ruby ve Rails'i bizim için ideal araçlar, gelecek yıllarda da kullanmaya devam etmeyi planladığımız araçlar haline getiriyor.

Braze'de çalışmak ister misiniz? Mühendislik, Ürün Yönetimi ve Kullanıcı Deneyimi ekiplerimizde çeşitli roller için işe alıyoruz. Açık rollerimiz ve kültürümüz hakkında daha fazla bilgi edinmek için kariyer sayfamıza göz atın .