19 puan yazan xguru 2020-08-10 | 3 yorum | WhatsApp'ta paylaş

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ı

Önceki yapı: nginx (açık kaynak sürüm) + python2 + Jinja2 + YAML

→ Tek bir şey değişse bile tüm sistemin yeniden dağıtılması gerekiyordu

→ Dinamik bölümler Lua ile geliştiriliyordu

→ Karmaşık mantık ise Go tabanlı proxy Bandaid içinde işleniyordu

Yaklaşık 10 yıl boyunca iyi çalıştı, ancak mevcut ortama artık pek uygun değil

→ İç ve dış (özel) API’ler giderek REST’ten gRPC’ye geçiyor, bu yüzden proxy’nin transcoding özelliğine ihtiyaç duyuluyor

→ Protocol Buffers, iç servis tanımlarının standartı haline geldi

→ Tüm yazılımlar, dil fark etmeksizin Bazel ile derlenip test ediliyor

→ Çalışanlar, başlıca altyapı projelerinin açık kaynak topluluklarına oldukça yoğun katkı veriyor

Nginx, operasyon açısından da sürdürmesi pahalı bir yapı

→ Config üretim mantığı fazla esnek ve YAML, Jinja2, Python arasında dağılmış durumda

→ İzleme, Lua / log ayrıştırma / sistem tabanlı izleme karışımından oluşuyor

→ Üçü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

→ 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ı

Bu yüzden, 10 yıl sonra ilk kez Nginx’in yerini alacak bir şey aramaya karar verdiler

  • Neden Bandaid’e (Dropbox’ın kendi geliştirdiği Go tabanlı proxy) geçmediler?

→ Go, C/C++’a göre daha fazla kaynak tüketiyor.

→ Go’nun TLS yığını FIPS desteği sunmuyor (ABD Federal Information Processing Standards)

→ İç araç olduğu için dış topluluktan destek almak mümkün değil

Bugünkü yapı: Envoy tabanlı trafik altyapısına geçiş

----- Envoy’un Nginx’ten daha iyi olduğu noktalar ------

  • Performans *

Nginx’in mimarisi event-driven / multi-process. SO_REUSEPORT & EPOLLEXCLUSIVE desteği var

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)

Bu da tail latency’ye yol açıyor ve bazen saniyeler düzeyinde gecikme oluşabiliyor

Envoy da benzer şekilde event-driven bir mimari kullanıyor, ancak process değil thread tabanlı

SO_REUSEPORT desteği var (BPF filtre desteğiyle birlikte), ayrıca libevent üzerinden event loop sağlıyor

Event loop içinde blocking I/O yok. Event logging de non-blocking şekilde uygulanmış.

Teorik olarak benzer performans özellikleri göstermeleri bekleniyordu ve çoğu iş yükü testinde gerçekten de benzerdi.

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ı.

İ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.)

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.

  • Gözlemlenebilirlik *

Ücretsiz Nginx sürümü, stub status modülü üzerinden yalnızca 7 istatistik sağlıyor

Bu doğal olarak yetersiz kaldığı için log_by_lua handler ekleyerek daha fazla istatistik sağlıyorlardı.

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.

Temel bir Envoy kurulumu, Prometheus formatında binlerce farklı metrik sağlıyor

Proxy trafik bilgilerinden sunucunun iç durum bilgilerine kadar,

cluster/upstream/virtual host bazında istatistikler ve listener bazında TCP/HTTP/TLS downstream istatistikleri gibi pek çok veri mevcut

Bu çeşitli istatistiklerin yanında Envoy, Tracing Provider’ın eklenti olarak kullanılmasına da izin veriyor.

Bu, yalnızca trafik ekibi için değil uygulama geliştiricileri için de faydalı.

Son olarak Envoy, gRPC üzerinden access log’ları stream edebiliyor.

Bu sayede trafik ekibinin syslog-to-hive köprüsünü destekleme yükü azalıyor.

Özel TCP/UDP listener eklemek yerine genel amaçlı bir gRPC servisi çalıştırmak çok daha kolay ve güvenli.

  • Entegrasyon *

Nginx’in entegrasyonu çok Unix tarzı. Configuration oldukça statik.

Config dosyalarına, TLS sertifikalarına, allowlist/blocklist gibi şeyler için dosyalara bağımlı.

Basit ve geriye dönük uyumlu olduğu için birkaç shell script ile otomasyon mümkün,

ancak sistem büyüdükçe test edilebilirlik ve standardizasyon giderek daha önemli hale geliyor.

Envoy’un bu entegrasyon için kendine özgü bir yaklaşımı var.

xDS adı verilen API’ler sunuyor ve protobuf ile gRPC kullanımını teşvik ediyor.

Envoy, bu xDS’lere sorgu göndererek dinamik kaynakları buluyor.

  • 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.

Dropbox içeride servisleri zaten gRPC üzerinden birbirine bağladığı için bu yaklaşım onlar için çok daha uygun.

  • Yapılandırma *

Nginx’in büyük avantajlarından biri, insanlar tarafından okunması kolay olan yapılandırma dosyalarıydı.

Ancak yapılandırma giderek karmaşıklaşıp otomatik üretildikçe bu avantaj ortadan kalktı.

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.

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.

Dropbox içinde protobuf yaygın olarak kullanıldığı için entegrasyonu da kolaylaştırıyor

  • Genişletilebilirlik *

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.

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

Envoy’u diğer web sunucularından ayıran en büyük farklardan biri WebAssembly (WASM) desteği.

Bu sayede Rust gibi farklı dillerle uzantı geliştirmeyi destekleyebiliyor.

Dropbox henüz WASM kullanmıyor, ancak bir gün proxy-wasm için Go SDK desteği gelirse bu değişebilir

  • Derleme ve test *

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

Nginx’te Perl tabanlı integration test’ler var ama unit test yok.

Envoy’un derleme sistemi zaten Bazel tabanlı ve bunu monorepo’larına kolayca entegre etmişler.

Ayrıca gtest/gmock tabanlı unit test’leri ve bir integration test framework’ü sağlıyor

  • Güvenlik *

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.

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.

  • Özellikler *

Bu bölümde öznel görüşler daha fazla, bu yüzden buna göre değerlendirmek gerekir

Nginx başlangıçta çok az kaynakla statik dosya sunan bir web sunucusu olarak ortaya çıktı.

Yani temel işlevleri static serving, caching ve range caching

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.

Backend’e HTTP/2 bağlantısı kuramıyor, çoklu bağlantılı gRPC proxy desteği yok, gRPC transcoding de yapamıyor.

Open-core lisans modeli nedeniyle bazı önemli özellikler “community version” içinde yer almıyor

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.

Web sunucusu özellikleri ise oldukça temel seviyede. Dosya sunamıyor, caching hâlâ geliştiriliyor, brotli desteği de yok vb.

Bu tür ortamlar için Envoy’u upstream cluster olarak kullanan bir Nginx kurulumu da işletiliyor

Envoy HTTP cache desteği kazandığında bu tür statik sunum ortamlarının da taşınabileceği öngörülüyor

Envoy, gRPC ile ilgili pek çok özelliği destekliyor

  • gRPC proxying

  • Backend’lere HTTP/2

  • gRPC → HTTP bridge (+ reverse.)

  • gRPC-WEB

  • gRPC JSON transcoder

Ayrıca Envoy, outbound proxy olarak da kullanılabiliyor

  • Egress Proxy

  • Courier gRPC kütüphanesi ile üçüncü taraf yazılımlar için service discovery

  • Topluluk *

Nginx geliştirme süreci merkezî ve büyük ölçüde kapalı.

Envoy geliştirmesi ise açık ve dağıtık. GitHub issue/PR üzerinden ilerliyor; mailing list/Slack gibi kanallarda da oldukça aktif

----- Dropbox’ın mevcut migration durumu -----

Nginx ve Envoy’u son altı aydır birlikte çalıştırıyorlar ve DNS üzerinden trafiği kademeli olarak taşıyorlar

Geçiş tamamen sorunsuz olmadı; küçük problemler yaşandı ama ciddi bir kesinti olmadı.

"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)

** Sıradaki işler **

  • HTTP/3 : Envoy da deneysel destek sunmaya başladı. UDP hızlandırması için Linux kernel yükseltildiğinde denemeyi planlıyorlar

  • İç xDS tabanlı load balancer ve Outlier Detection

  • WASM tabanlı Envoy genişletmeleri

  • Bandaid’i (Go tabanlı proxy) Envoy ile değiştirmek

  • Envoy Mobile ile mobil uygulamalarda da Envoy kullanmak

3 yorum

 
baeba 2020-08-13

Güzel içeriği kısa ve öz

özetlediğiniz için

teşekkür ederim.

 
before30 2020-08-11

Teşekkür ederim. :)

 
loslch 2020-08-11

Ayrıntılı özetiniz ve nazik yorumlarınız anlamama çok yardımcı oldu. Teşekkür ederim :)