2 puan yazan GN⁺ 2025-07-07 | 1 yorum | WhatsApp'ta paylaş
  • CGI programlama ile bile günde 200 milyondan fazla web isteğini işlemek mümkün
  • Son dönemdeki donanım performansı artışı sayesinde CGI yaklaşımının dezavantajları büyük ölçüde azaldı
  • Go ve SQLite kullanan bir CGI programı, 16 iş parçacıklı bir CPU üzerinde olağanüstü performans gösterdi
  • CGI, birden fazla CPU çekirdeğini kullanma konusunda özellikle uygun bir yapı sunuyor
  • Modern teknoloji sayesinde geçmişteki web uygulaması geliştirme yöntemleri bugün de yeterince pratik olabilir

CGI'nin geçmişi ve bugünü

  • 1990'ların sonlarında yazar, web geliştirmeye CGI ile başladı ve o dönemde NewsPro gibi sistemler kullandı
  • CGI, her web isteğinde yeni bir süreç başlatıp sonlandırdığı için yüksek ek yük oluşturuyordu
  • Bu nedenle daha verimli PHP, FastCGI gibi alternatif teknolojiler geliştirildi

Donanım performansındaki gelişim

  • Son 20 yılı aşkın sürede bilgisayar hızı ve performansı büyük ölçüde arttı
  • 2020'de yazar, Go ve Rust ile geliştirilen araçları (ripgrep gibi) kullanırken süreç çalıştırma yaklaşımının pratikliğini yeniden fark etti

Modern CGI yaklaşımının avantajları

  • Go ve Rust gibi hızlı çalışan dillerle CGI geliştirildiğinde, eski tip CGI'nin dezavantajlarının çoğu ortadan kalkıyor
  • CGI programları, her istek için ayrı bir süreçte çalıştığı için çok çekirdekli CPU kullanımına son derece uygun
    • Örneğin 16 iş parçacıklı bir ortamda saniyede 2400'den fazla istek = günde 200 milyon+ istek işleme potansiyeli doğrulandı
    • Büyük sunucular 384 veya daha fazla CPU iş parçacığı sunabiliyor

Geliştirme kültürüne dair içgörüler

  • Bugün Go ve Rust gibi dillerin yaygınlaşmasıyla 1990'lardaki CGI yaklaşımı yeniden anlam kazanabilir
  • Yine de bu yöntem hâlâ her ortam için uygun değil ve ana akım bir yaklaşım olarak önerilmiyor
  • Önemli nokta, bugün CGI'nin eskisi kadar verimsiz bir çözüm olmadığının deneysel olarak gösterilmesi

Sonuç

  • Modern donanım ve hızlı dillerin desteğiyle CGI programlama, geçmişle kıyaslanamayacak bir performans sergiliyor
  • Çoklu süreç yaklaşımının avantajlarını en üst düzeye çıkaran bir örnek olarak, web geliştiriciler için ilgi çekici çıkarımlar sunuyor

1 yorum

 
GN⁺ 2025-07-07
Hacker News görüşleri
  • Günümüzde Python ile bile CGI oldukça hızlı hissettiriyor
    CGI betiği başlangıçta CPU’da 400 milisaniye harcasa bile, sunucuda 64 çekirdek varsa saniyede 160 istek işlenebilir; bu da sunucu başına günde 14 milyon trafiği kaldırmak demek
    Günlük yüz milyonlar seviyesindeki trafiklerde bile (statik varlıklar hariç) CGI süreç başlangıcı darboğaz olmak zorunda değil
    Eskiden bu tür teknolojilerin "sıkıcı derecede istikrarlı teknoloji" olduğu için Python standart kütüphanesinde hep bulunduğunu düşünürdüm, ama günümüzde Python bakımcıları istikrar ve geriye dönük uyumluluğa daha olumsuz bakıyor
    Bu yüzden fazla 'sıkıcı ve istikrarlı' modüller standart kütüphaneden çıkarılıyor; nitekim cgi modülü 3.13 sürümünde silindi
    Yaklaşık 25 yıldır Python’ı prototipleme için kullanma alışkanlığım yüzünden ama artık pişmanım
    Şu sıralar JS ile Lua arasında kararsızım

    • cgi'nin kaldırılmasıyla ilgili resmi açıklama bağlantısı: PEP 594 cgi
      Bu bağlantı 2000 yılında (25 yıl önce) yazılmış PEP 206 belgesine gidiyor; orada bile "cgi paketi kötü tasarlanmış ve üzerinde çalışması zor" deniyor
      jackrosenthal/legacy-cgi deposunda standart kütüphane modülünün bire bir yerine geçebilen bir drop-in replacement görülebilir

    • Python geliştiricileri sadece cgi adlı modülü çıkardı
      CGI betiği uygulaması hâlâ http.server modülündeki CGIHTTPRequestHandler ile destekleniyor
      Aslında cgi modülünde HTML form verisini ayrıştıran birkaç işlevden fazlası yoktu

    • Python’da cgi modülünün standart kütüphaneden çıkmasını eleştirmek anlaşılır, ama örnek gösterilen JS zaten baştan standart kütüphaneye sahip değil
      Lua’nın da stdlib içinde bir CGI modülü olmadığına dikkat çekiliyor

    • Ben kişisel olarak PHP ya da JS tercih ederim
      Bu tür durumlarda kutudan çıktığı gibi JIT gelmesi kullanışlı
      Python’ı 1.6’dan beri kullanıyorum ama çoğunlukla sadece OS betikleme için
      Eskiden Tcl’yi Apache veya IIS modülleriyle entegre edip modülleri sürekli C ile yeniden yazdığım bir dönem yaşamıştım (1999~2003)

    • Bir CGI betiği 400 milisaniye CPU kullanıyorsa, o endpoint’in yanıt süresi de en az o kadar olur; bu da kullanılabilirliği etkiler

  • Kısa süre önce 350 dolarlık mini bir sunucuya golang binary’si, rabbitmq, redis ve MySQL kurup aynı sunucuda sürdürülebilir biçimde 5.000 req/s işledim
    24 saatte bu, 400 milyon istek kapasitesi demek
    Günümüzde ücretsiz araçların ne kadar harika olduğunu bir kez daha hissettim
    Yine de bulut maliyetlerinin çok yüksek olduğunu düşünüyorum
    Elbette bire bir karşılaştırma zor, ama geliştirme ve tuning işlerini evin bodrumundaki sunucuda doğrudan yapabilmiş olmak ayrıca tatmin ediciydi

    • Kubernetes tabanlı mikroservis yığınları kullanıp geliştirme hızını 10 kat yavaşlatan durumlar da var
      Pek çok kişi sunucuların saniyede sadece 1 istek işleyen makineler olmadığını bilmiyor
      Sırf Google yapıyor diye peşinden gidip aşırı overhead ödüyoruz
      Ben de ekibimde çok iyi işleyen 'modüler monolitik' mimari hakkında bir şeyler yazmam gerektiğini düşünüyorum

    • Yan projelerimi evde barındırmayı denedim ama elektrik kesintisi, ISP kesintisi, uzaktan erişim sorunu, disk arızası gibi riskler büyük
      Sonunda kendi zaman maliyetini de katınca ekonomik faydası belirsiz kalıyor
      Bulut hizmetleri ölçek ekonomisinden faydalandığı için pratikte makul bir seçim olabiliyor

    • Bulut şart değil; bir hosting sağlayıcısından dedicated server kiralamak da mümkün
      Tabii bant genişliği/trafik sınırları oluyor
      Bulutun ana akım olmasının nedeni, VC’lerin ve yatırımcıların bu şirketlerde pay sahibi olması ya da "ya sınırsız trafik patlarsa" kaygısı
      Bulut satış uzmanları yatırımcıların bu kaygısını ustaca kullanıyor

    • Herkes illa bulut kullanmıyor

    • Gerçek hizmetlerde VM maliyetinin yüksek olmasının nedeni yüksek performanslı compute değil, devasa yerel disk kapasitesi ihtiyacı
      Çok güçlü hesaplama gerekmiyor; 20TB’lık 4 disk ve makul bir CPU ile bile harika bir servis tasarlanabilir
      Bulutta böyle bir kombinasyon bulmak neredeyse imkânsız

  • cgi-bin içinden DB’ye erişmek gerektiğinde, her seferinde sürecin yeniden DB bağlantısı kurması can sıkıcı
    Kod bellekte çalışıyorsa (fastcgi gibi), sadece başlangıç süresi kısalmaz; aynı zamanda DB connection pool ya da thread başına kalıcı bağlantı tutmak da mümkün olur

    • Büyük ölçekte çalıştırınca DB bağlantı sayısı fazla artıp veritabanını zorlayabiliyor
      "Python tek iş parçacıklı, o yüzden çok süreç; Python yavaş, o yüzden daha çok süreç" mantığıyla çok sayıda süreç işletiliyor
      Sonunda shared connection pool’u (pg bouncer gibi) Python süreçlerinin dışına taşımak ve çeşitli tuning yapmak gerekiyor
      En sonunda da daha yönetilebilir bir dille (çok iş parçacığı desteği olan ve performansı daha iyi bir dille) yeniden yazınca sistem çok daha basit hâle gelmişti

    • Bu yüzden CGI sonunda istekler arasında bilgi tutabilen bir modele (fastcgi gibi) evrildi

    • Geleneksel olarak ayrı bir daemon kaldırıp proxy görevi verdikleri de olurdu; ayrıca Unix soketleri kullanıldığında TCP/IP’ye göre çok daha verimli olurdu

    • UDP kullanılması gerektiğini söyleyen bir görüş

  • Benim için inetd doğrudan CGI’nin kendisi
    Bu sayede internet çok daha eğlenceli gelirdi
    Bir zamanlar inetd ile çeşitli shell betikleri, hatta sadece Bash ile yazılmış HTTP bile çalıştırmıştım
    Eski VPS’ler, yedek ya da sürüm kontrolü olmayan dizüstüler artık yok ama güzel anılar kaldı
    Dağıtım da Makefile + scp ile basitti; testler de netcat ve grep ile yazılmış Bash betikleriyle yapılabiliyordu
    Gerçekten yaşaması güzel bir çağdı

  • Bir hello world uygulamasının 2400 rps’ye ulaşmasının günümüz donanımına göre pek etkileyici olmadığı izlenimi var
    Kod da daha basit hâle gelmemişken, ne uğruna performanstan vazgeçildiği sorgulanıyor

    • 2000 rps’den fazlasına ihtiyaç yoksa bu zaten sorun değil
      Böyle bir trafiğe ihtiyaç duyan sitelerin çok az olduğu savunuluyor

    • Sayı olarak çok yüksek görünmeyebilir ama pratikte birçok ortam için yeterli
      HN geliştiricilerinin söz ettiği 'hug of death' (belirli bir anda ani trafik patlaması) durumlarına bile dayanabilecek bir seviye

  • Bizim şirkette hâlâ cgi-bin dizini üzerinden basit iç web uygulamalarını hızlıca ayağa kaldırma yöntemi kullanılıyor
    Basit tutulduğunda geliştirme verimliliği çok yüksek
    CGI olsa bile http/1.0'ı doğrudan print etmek gerekmiyor; Python’ın wsgiref.handlers.CGIHandler aracıyla herhangi bir WSGI uygulaması CGI betiği olarak çalıştırılabiliyor
    Flask örnek kodu da aşağıdaki kadar basit

     import wsgiref.handlers, flask
     app = flask.Flask(__name__)
     wsgiref.handlers.CGIHandler().run(app)
    

    İş ortamında betikleri uwsgi'nin CGI eklentisiyle çalıştırıyoruz
    Apache ya da lighttpd üzerinde mod_cgi çalıştırmaktan çok daha basit ve daha esnek hissettiriyor
    uwsgi sistem düzeyinde çalıştığı için systemd’nin tüm hardening ve sandboxing imkânlarından yararlanabiliyor
    Ayrıca uwsgi’nin CGI işleyişinde her dosya türü için ayrı interpreter belirtilebiliyor

     cgi = /cgi-bin=/webapps/cgi-bin/src
     cgi-allowed-ext = .py
     cgi-helper = .py=/webapps/cgi-bin/venv/bin/python3 # all dependencies go here
    

    İlk baytın gönderilmesine kadar 250~350 ms sürüyor; bizim kullanımımız için gayet kabul edilebilir
    uwsgi CGI belgeleri

    • Güzel ipucu paylaşımı
      wsgiref.handlers.CGIHandler aracının henüz deprecated olmamış olması faydalı bir bilgi
  • Dün tartışılan ilgili başlık bağlantı

  • Son dönemde yan projelerde Apache kullanırken .htaccess özelliğini faydalı bulduğum oldu
    Herhangi bir dizine sadece bir .htaccess dosyası koyarak her istekte ek sunucu ayarlarının yüklenmesini sağlayabiliyorsunuz
    htaccess resmi belgeleri
    Eskiden her istekte disk erişimi overhead’i yarattığı için performans açısından .htaccess kullanımından kaçınılması ve mümkünse ana yapılandırmaya taşınması önerilirdi
    Ama artık SSD’ler ve RAM yeterince güçlü; elbette performanstan çok az kaybettiriyor ama CPU’lar da yeterince iyi olduğu için çoğu durumda göz ardı edilebilir
    [StaticPatch projem][https://github.com/StaticPatch/StaticPatch/tree/main] içinde de bunu uygulayarak kullanıyorum

    • PHP’nin yaratıcısı Rasmus Lerdorf’tan ünlü bir söz
      "Ben gerçek bir programcı değilim, sadece çalışmasını sağlar ve yoluma devam ederim. Gerçek programcılar 'bunda ciddi bir bellek sızıntısı var, düzeltilmeli' der. Ben ise Apache’yi her 10 istekte bir yeniden başlatırım"
      PHP o günden sonra uzun bir yol kat etti; ilk hatalarını aşarak büyük ölçüde gelişti
      "PHP 8’de kodum ne kadar azsa o kadar iyi" dediğine dair bir anekdot da var

    • Apache neden dosya sistemini izleyip sadece değiştiğinde okumuyor da, her istekte gereksiz disk erişimi yaptırıyor anlamıyorum
      Sonuç olarak HTTP isteklerinin %99,99’unu yavaşlatıyor deniyor

  • Son zamanlarda hızlı prototipleme için bu tür bir yapıyı iş akışımda düşünmeye başladım
    JIT dillerde fastcgi benzeri bir yapı yoksa import darboğaz olabiliyor
    Kullandığım h2o web sunucusunda mruby ve fast-cgi handler ayar dosyalarının basit olması, yerel script işleri için çok uygun
    h2o fastcgi belgeleri
    Bir başka avantaj da, müşterilerin kendi özel kodlarını ekleyebilmesi için yerel yazılımı genişletmek gerektiğinde işe yaraması
    Örneğin eskiden genişletme için MCP kullanmak gerekirdi ama artık CGI ile yapılandırılmış istekleri uygulamak yeterli

    • Son kullanıcı ortamında MCP ön ucu olarak CGI programlarını bağlamak da ilginç bir fikir olabilir
      MCP hizmetlerinin de pekâlâ CGI ile uygulanabileceği düşünülüyor
      Spesifikasyona daha yakından bakma isteği var

    • fastcgi kullanınca CGI’nin avantajlarının neredeyse hepsinin kaybolduğu sorgulanıyor

  • Geçmişte C programları ile CGI kombinasyonunu bizzat kullandım
    O zamanlar 100’den fazla çekirdek ya da bol RAM yoktu; en fazla 1GB bellekle bile çalışıyordu
    O günlerde yapılabildiyse, bugün çok daha kolay olması gerekir diye düşünüyorum

    • 1995’te Amazon, CGI yöntemiyle C++ çalıştırılabilir dosyaları kullanıyordu
      Yük dengeleme gereksinimi doğduktan sonra ölçekleme zorlaştı ama öncesinde gayet iyi çalışıyordu
      Bu arada front-end ve back-office için ayrı iki çalıştırılabilir dosya vardıydı