19 puan yazan xguru 2020-08-10 | 3 yorum | WhatsApp'ta paylaş
<p>On milyonlarca eşzamanlı bağlantı, saniyede milyonlarca istek ve terabayt düzeyinde bant genişliği kullanan Dropbox’ın, Nginx’e kıyasla Envoy’un avantajlarını çok iyi anlattığı bir yazı<br /> <br /> Önceki yapı: nginx (açık kaynak sürüm) + python2 + Jinja2 + YAML <br /> → Tek bir şey değişse bile tüm sistemin yeniden dağıtılması gerekiyordu<br /> → Dinamik bölümler Lua ile geliştiriliyordu<br /> → Karmaşık mantık ise Go tabanlı proxy Bandaid içinde işleniyordu<br /> <br /> Yaklaşık 10 yıl boyunca iyi çalıştı, ancak mevcut ortama artık pek uygun değil<br /> → İç ve dış (özel) API’ler giderek REST’ten gRPC’ye geçiyor, bu yüzden proxy’nin transcoding özelliğine ihtiyaç duyuluyor<br /> → Protocol Buffers, iç servis tanımlarının standartı haline geldi <br /> → Tüm yazılımlar, dil fark etmeksizin Bazel ile derlenip test ediliyor<br /> → Çalışanlar, başlıca altyapı projelerinin açık kaynak topluluklarına oldukça yoğun katkı veriyor<br /> <br /> Nginx, operasyon açısından da sürdürmesi pahalı bir yapı<br /> → Config üretim mantığı fazla esnek ve YAML, Jinja2, Python arasında dağılmış durumda<br /> → İzleme, Lua / log ayrıştırma / sistem tabanlı izleme karışımından oluşuyor<br /> → Üçüncü taraf modüllere bağımlılık arttıkça kararlılık/performans etkileniyor ve sık yükseltmeler ek maliyet çıkarıyor <br /> → nginx’in kendi dağıtım ve süreç yönetimi diğer servislerden oldukça farklı. syslog, logrotate gibi temel sistemlerden çok farklı şeylere yoğun biçimde bağımlı<br /> <br /> Bu yüzden, 10 yıl sonra ilk kez Nginx’in yerini alacak bir şey aramaya karar verdiler<br /> <br /> * Neden Bandaid’e (Dropbox’ın kendi geliştirdiği Go tabanlı proxy) geçmediler? <br /> → Go, C/C++’a göre daha fazla kaynak tüketiyor. <br /> → Go’nun TLS yığını FIPS desteği sunmuyor (ABD Federal Information Processing Standards)<br /> → İç araç olduğu için dış topluluktan destek almak mümkün değil <br /> <br /> Bugünkü yapı: Envoy tabanlı trafik altyapısına geçiş <br /> <br /> ----- Envoy’un Nginx’ten daha iyi olduğu noktalar ------<br /> <br /> * Performans *<br /> <br /> Nginx’in mimarisi event-driven / multi-process. SO_REUSEPORT &amp; EPOLLEXCLUSIVE desteği var<br /> Event loop tabanlı olsa da tamamen non-blocking değil. Dosya açma/loglama sırasında event loop durabiliyor. (`aio`, `aio_write` ve Threadpool etkin olsa bile)<br /> Bu da tail latency’ye yol açıyor ve bazen saniyeler düzeyinde gecikme oluşabiliyor<br /> <br /> Envoy da benzer şekilde event-driven bir mimari kullanıyor, ancak process değil thread tabanlı <br /> SO_REUSEPORT desteği var (BPF filtre desteğiyle birlikte), ayrıca libevent üzerinden event loop sağlıyor <br /> Event loop içinde blocking I/O yok. Event logging de non-blocking şekilde uygulanmış.<br /> <br /> Teorik olarak benzer performans özellikleri göstermeleri bekleniyordu ve çoğu iş yükü testinde gerçekten de benzerdi.<br /> Ancak Nginx’in long tail tarafında gecikme süresi daha yüksekti. Bunun nedeni yoğun I/O sırasında event loop’un durmasıydı.<br /> <br /> İstatistik toplama devre dışıyken Nginx, Envoy ile benzer performans gösteriyor; ancak içeride kullanılan Lua tabanlı istatistik toplama aracı, yüksek RPS testlerinde Nginx’i 3 kat yavaşlatıyordu. (Bunun nedeni mutex ile senkronize edilen `lua_shared_dict`.) Dropbox’ın istatistik toplama yönteminde sorunlar olduğu doğru, ancak bunu verimli biçimde yeniden geliştirmekten vazgeçtiler. (Çünkü Nginx içine instrumentation eklemenin ileride yükseltmeleri zorlaştıracağını düşündüler.)<br /> <br /> Sonuç olarak bu sorunlar Envoy’da olmadığı için, geçişten sonra eski Nginx’in kullandığı sunucuların en fazla %60’ını serbest bırakabildiler.<br /> <br /> * Gözlemlenebilirlik *<br /> <br /> Ücretsiz Nginx sürümü, stub status modülü üzerinden yalnızca 7 istatistik sağlıyor <br /> Bu doğal olarak yetersiz kaldığı için `log_by_lua` handler ekleyerek daha fazla istatistik sağlıyorlardı.<br /> Ayrıca error.log ayrıştırıcısı üzerinden hata bilgisi dışa aktarılıyor ve nginx iç durum değerlerini dışa vermek için ayrı bir exporter da bulunuyordu.<br /> <br /> Temel bir Envoy kurulumu, Prometheus formatında binlerce farklı metrik sağlıyor <br /> Proxy trafik bilgilerinden sunucunun iç durum bilgilerine kadar,<br /> cluster/upstream/virtual host bazında istatistikler ve listener bazında TCP/HTTP/TLS downstream istatistikleri gibi pek çok veri mevcut<br /> <br /> Bu çeşitli istatistiklerin yanında Envoy, Tracing Provider’ın eklenti olarak kullanılmasına da izin veriyor.<br /> Bu, yalnızca trafik ekibi için değil uygulama geliştiricileri için de faydalı.<br /> <br /> Son olarak Envoy, gRPC üzerinden access log’ları stream edebiliyor.<br /> Bu sayede trafik ekibinin syslog-to-hive köprüsünü destekleme yükü azalıyor.<br /> Özel TCP/UDP listener eklemek yerine genel amaçlı bir gRPC servisi çalıştırmak çok daha kolay ve güvenli.<br /> <br /> * Entegrasyon *<br /> <br /> Nginx’in entegrasyonu çok Unix tarzı. Configuration oldukça statik.<br /> Config dosyalarına, TLS sertifikalarına, allowlist/blocklist gibi şeyler için dosyalara bağımlı.<br /> Basit ve geriye dönük uyumlu olduğu için birkaç shell script ile otomasyon mümkün,<br /> ancak sistem büyüdükçe test edilebilirlik ve standardizasyon giderek daha önemli hale geliyor.<br /> <br /> Envoy’un bu entegrasyon için kendine özgü bir yaklaşımı var.<br /> xDS adı verilen API’ler sunuyor ve protobuf ile gRPC kullanımını teşvik ediyor.<br /> Envoy, bu xDS’lere sorgu göndererek dinamik kaynakları buluyor.<br /> <br /> - Bu xDS artık Envoy’un ötesine geçerek Universal Data Place API (UDPA) adıyla L4/L7 load balancer’lar için fiilî standart olmaya doğru evriliyor; bizim deneyimimize göre de bu iyi ilerliyor. Envoy dışındaki Katran eBPF/XDP L4 load balancer’da da UDPA kullanmayı planlıyorlar.<br /> <br /> Dropbox içeride servisleri zaten gRPC üzerinden birbirine bağladığı için bu yaklaşım onlar için çok daha uygun.<br /> <br /> * Yapılandırma *<br /> <br /> Nginx’in büyük avantajlarından biri, insanlar tarafından okunması kolay olan yapılandırma dosyalarıydı. <br /> Ancak yapılandırma giderek karmaşıklaşıp otomatik üretildikçe bu avantaj ortadan kalktı.<br /> Dropbox’ta yapılandırma Python2, Jinja2, YAML vb. ile üretildiği için veri modeli de iç içe geçmiş ve karmaşık hale gelmişti.<br /> <br /> Envoy, yapılandırma için birleşik bir veri modeline sahip. Tüm ayarlar Protocol Buffer içinde tanımlanıyor. Bu, veri modelleme sorunlarını çözüyor ve ayarlara tip bilgisi ekliyor.<br /> Dropbox içinde protobuf yaygın olarak kullanıldığı için entegrasyonu da kolaylaştırıyor <br /> <br /> * Genişletilebilirlik * <br /> <br /> Nginx’i genişletmek için C modülleri yazmak gerekiyor. Güvenli modül geliştirmek için kıdemli geliştiricilere ihtiyaç var. Daha hafif modül geliştirme için Perl / JS arayüzleri sunsa da bunlar çok sınırlı. Bu yüzden en yaygın yöntem `lua-nginx-module` kullanmak. <br /> <br /> Envoy’un ana genişleme mekanizması C++ eklentileri; belgeleri nginx kadar iyi olmasa da kullanımı oldukça basit. Bunda temiz, iyi yorumlanmış arayüzlerin yanı sıra C++14 dili ve standart kütüphane de etkili <br /> <br /> Envoy’u diğer web sunucularından ayıran en büyük farklardan biri WebAssembly (WASM) desteği.<br /> Bu sayede Rust gibi farklı dillerle uzantı geliştirmeyi destekleyebiliyor. <br /> Dropbox henüz WASM kullanmıyor, ancak bir gün proxy-wasm için Go SDK desteği gelirse bu değişebilir<br /> <br /> * Derleme ve test *<br /> <br /> Nginx temel olarak özel shell tabanlı yapılandırma ve `make` tabanlı derleme kullanıyor. Basit ve iyi bir yaklaşım olsa da bunu Bazel ile derlenen bir monorepo’ya entegre etmek ciddi çaba gerektiriyor <br /> Nginx’te Perl tabanlı integration test’ler var ama unit test yok.<br /> <br /> Envoy’un derleme sistemi zaten Bazel tabanlı ve bunu monorepo’larına kolayca entegre etmişler.<br /> Ayrıca gtest/gmock tabanlı unit test’leri ve bir integration test framework’ü sağlıyor<br /> <br /> * Güvenlik *<br /> <br /> Nginx kod tabanı oldukça küçük ve dış bağımlılıkları da az olduğu için güvenlik açığı sayısı çok değil.<br /> <br /> Envoy’un kod tabanı daha büyük olduğundan doğal olarak saldırı yüzeyi daha geniş görünüyor. Bunun için Envoy, modern güvenlik pratiklerine yoğun biçimde dayanıyor. AddressSanitizer, ThreadSanitizer, MemorySanitizer vb. araçlar kullanılıyor. <br /> <br /> * Özellikler * <br /> <br /> Bu bölümde öznel görüşler daha fazla, bu yüzden buna göre değerlendirmek gerekir<br /> <br /> Nginx başlangıçta çok az kaynakla statik dosya sunan bir web sunucusu olarak ortaya çıktı. <br /> Yani temel işlevleri static serving, caching ve range caching<br /> Proxy açısından bakıldığında Nginx, günümüz altyapısının gerektirdiği pek çok özelliği barındırmıyor. <br /> Backend’e HTTP/2 bağlantısı kuramıyor, çoklu bağlantılı gRPC proxy desteği yok, gRPC transcoding de yapamıyor.<br /> Open-core lisans modeli nedeniyle bazı önemli özellikler “community version” içinde yer almıyor<br /> <br /> Envoy ise en baştan ingress/egress proxy olarak tasarlandı ve gRPC yükünün yoğun olduğu ortamlarda yaygın kullanılıyor.<br /> Web sunucusu özellikleri ise oldukça temel seviyede. Dosya sunamıyor, caching hâlâ geliştiriliyor, brotli desteği de yok vb. <br /> Bu tür ortamlar için Envoy’u upstream cluster olarak kullanan bir Nginx kurulumu da işletiliyor <br /> Envoy HTTP cache desteği kazandığında bu tür statik sunum ortamlarının da taşınabileceği öngörülüyor <br /> <br /> Envoy, gRPC ile ilgili pek çok özelliği destekliyor<br /> - gRPC proxying<br /> - Backend’lere HTTP/2<br /> - gRPC → HTTP bridge (+ reverse.) <br /> - gRPC-WEB <br /> - gRPC JSON transcoder<br /> <br /> Ayrıca Envoy, outbound proxy olarak da kullanılabiliyor <br /> - Egress Proxy<br /> - Courier gRPC kütüphanesi ile üçüncü taraf yazılımlar için service discovery <br /> <br /> * Topluluk *<br /> <br /> Nginx geliştirme süreci merkezî ve büyük ölçüde kapalı. <br /> Envoy geliştirmesi ise açık ve dağıtık. GitHub issue/PR üzerinden ilerliyor; mailing list/Slack gibi kanallarda da oldukça aktif </p><p>----- Dropbox’ın mevcut migration durumu -----<br /> <br /> Nginx ve Envoy’u son altı aydır birlikte çalıştırıyorlar ve DNS üzerinden trafiği kademeli olarak taşıyorlar <br /> Geçiş tamamen sorunsuz olmadı; küçük problemler yaşandı ama ciddi bir kesinti olmadı.<br /> "unusual" ya da "non-RFC" davranışlar nedeniyle karşılaştıkları sorunlara yönelik çözümleri de derlemişler (ayrıntılar için asıl metne bakılabilir)<br /> <br /> ** Sıradaki işler **<br /> <br /> - HTTP/3 : Envoy da deneysel destek sunmaya başladı. UDP hızlandırması için Linux kernel yükseltildiğinde denemeyi planlıyorlar<br /> - İç xDS tabanlı load balancer ve Outlier Detection<br /> - WASM tabanlı Envoy genişletmeleri <br /> - Bandaid’i (Go tabanlı proxy) Envoy ile değiştirmek <br /> - Envoy Mobile ile mobil uygulamalarda da Envoy kullanmak</p>

3 yorum

 
baeba 2020-08-13
<p>Güzel içeriği kısa ve öz<br /> özetlediğiniz için<br /> teşekkür ederim.</p>
 
before30 2020-08-11
<p>Teşekkür ederim. :)</p>
 
loslch 2020-08-11
<p>Ayrıntılı özetiniz ve nazik yorumlarınız anlamama çok yardımcı oldu. Teşekkür ederim :)</p>