2 puan yazan GN⁺ 2025-07-07 | 1 yorum | WhatsApp'ta paylaş
  • Jake Gold, 16 iş parçacıklı AMD 3700X üzerinde bir Go + SQLite CGI programı çalıştırarak 1990'lar tarzı CGI'ın modern donanımda ne kadar dayanabildiğini test etti
  • Sonuçlar, sıradan donanımlarda bile saniyede 2400'den fazla, günde 200 milyondan fazla isteğin işlenebildiğini gösteriyor
  • CGI, her istek için bir süreci başlatıp çalıştırdığı ve sonra sonlandırdığı için geçmişte yüksek ek yük oluşturuyordu; bunu azaltmak için PHP ve FastCGI gibi yaklaşımlar ortaya çıktı
  • Simon Willison, 2020'de datasette-ripgrep içinde Rust tabanlı ripgrep CLI'ını çağırarak aramaları işledi ve web isteği sırasında süreç çalıştırmaktan kaçınmak gerektiğine dair eski inancını değiştirdi
  • Go ve Rust gibi hızlı başlayan diller ile çoklu CPU ortamlarında CGI tarzı işleme, eskisine kıyasla daha gerçekçi bir seçenek olabilir; ancak genel olarak önerilen varsayılan yaklaşım değildir

Modern donanımda CGI performansına yeniden bakış

  • Serving 200 million requests per day with a cgi-bin, Jake Gold'un Go + SQLite CGI programı ile 1990'lar tarzı CGI'ın performansını test ettiği bir yazı
  • Test ortamı, 16 iş parçacıklı AMD 3700X tabanlı bir sistem
  • Temel sonuç, CGI ile bile sıradan donanımda saniyede 2400'den fazla, günde 200 milyondan fazla isteğin işlenebilmesi
  • CGI, gelen her istek için ayrı bir süreç başlatıp çalıştıran ve ardından sonlandıran bir yöntem
  • İlk dönem web topluluğu bu ek yükten kaçınmak için kodu bellekte sürekli tutup ilave maliyeti azaltan PHP ve FastCGI çözümlerini geliştirdi

CGI'ın eskisi kadar kötü olmayabileceğinin nedenleri

  • Geçmişte CGI'ın darboğazlarından biri, web betiklerinin Perl, Python, Java gibi çok hızlı başlatılma hedefiyle tasarlanmamış dillerle yazılmasıydı
  • Bugün Go ve Rust kullanıldığında CGI tarzı istek işleme çok daha verimli çalışabilir
  • Simon Willison, 2020'de datasette-ripgrep geliştirirken Rust ile yazılmış ripgrep CLI aracını shell üzerinden çağırarak arama yaptı ve iyi sonuçlar elde etti
  • CGI programları ayrı süreçler olarak çalıştığı için birden fazla CPU kullanan yapılarla da iyi uyum sağlayabilir
    • Modern sunucular 384 CPU iş parçacığına sahip olabilir
    • Küçük bir VM bile 16 CPU barındırabilir
    • CPU ve bellek performansı da geçmişe göre büyük ölçüde hızlandı
  • 1998 tarzı web uygulaması yazma yaklaşımı, Go ve Rust ile birleştiğinde ilginç bir deney konusu olabilir; ancak çoğu servisin izlemesi gereken varsayılan yol değildir

1 yorum

 
GN⁺ 2025-07-07
Hacker News yorumları
  • Python gibi bir şey kullansanız bile günümüzde CGI oldukça hızlı
    Bir CGI betiğinin başlaması CPU’da 400 ms sürüyorsa ve sunucu 64 çekirdekliyse, saniyede 160 istek; sunucu başına günde 14 milyon hit işleyebilir
    Statik varlıklar hariç günde birkaç milyon istekte bile zorlanan bir web servisi için darboğaz CGI sürecinin başlama süresi değildir
    Eskiden buna “Python standart kütüphanesinde uzun süredir desteklenen sıkıcı bir teknoloji” derdim; ama kalan Python bakımcıları kararlılığı ve geriye dönük uyumluluğu zararlı görüyor gibi ve fazlasıyla sıkıcı, kararlı modülleri standart kütüphaneden kaldırıp durdular
    cgi modülü Python 3.13’te kaldırıldı
    Son 25 yılın çoğunda her gün kullandığım için prototiplemede hâlâ Python kullanma alışkanlığım var; ama artık buna üzülüyorum ve JS ile Lua arasında kararsızım

    • cgi’nin kaldırılmasının gerekçesi https://peps.python.org/pep-0594/#cgi adresinde
      İlginç şekilde, orada 14 Temmuz 2000 tarihli, yani 25 yıl önceki https://peps.python.org/pep-0206/ bağlantısı veriliyor; o zaman da cgi paketi “kötü tasarlanmış ve artık düzeltilmesi neredeyse imkânsız” diye tanımlanmıştı
      https://github.com/jackrosenthal/legacy-cgi paketi, standart kütüphane modülünün drop-in alternatifini sağlıyor gibi
    • Python bakımcılarının kaldırdığı şey cgi adlı modül; CGI betikleri uygulamaya yönelik desteğin kendisi değil
      Bu destek http.server modülündeki CGIHTTPRequestHandler’da hâlâ duruyor
      cgi modülünde olanlar yalnızca HTML form verilerini ayrıştıran birkaç fonksiyondan ibaretti
    • Python’ın standart kütüphaneden CGI’yi kaldırmasına kızılmasını anlıyorum
      Ama ardından alternatif olarak standart kütüphanesi bile olmayan JS’yi düşünmeyi pek anlayamıyorum
      Lua’nın standart kütüphanesinde de CGI modülü yok
    • Eskiden yüksek performanslı web bir tür teknik sanattı
      Şimdi ise daha çok, hızlıca yayına çıkmak için eklenmiş akıl almaz derecede savurgan parçaları bulup onları durdurmaya benziyor
      Düzgün denerseniz uygulama, depolama erişimi dışında neredeyse hiç gecikme eklemeyebilir
    • Bu tür durumlarda JIT’i varsayılan olarak gelen PHP veya JS tarafını daha çok tercih ederim
      Python’ı 1.6’dan beri öğrendim ama çoğunlukla işletim sistemi betikleme işleri için kullandım
      1999–2003 arasında Apache ve IIS modüllerinde Tcl kullanıp modülleri sürekli C ile yeniden yazarak çok fazla dersi zor yoldan öğrendim
  • Yakın zamanda 350 dolarlık bir mini sunucuda Golang binary’si, RabbitMQ, Redis ve MySQL’i aynı makineye kurup test ettim; saniyede 5.000 isteği sürekli işledi
    Bunu 24 saate vurunca 400 milyon istek ediyor
    Günümüzde ücretsiz araçların ne kadar harika olduğuna şaşıyorum; buna rağmen bulut sağlayıcılarına bu kadar çok para ödememiz de şaşırtıcı
    Tamamen birebir bir karşılaştırma değil ama bodrumdaki makinede her şeyi geliştirip ayarlama süreci gerçekten güzeldi

    • Bir sunucunun saniyede 1 istekten çok daha fazlasını işleyebileceğini bilmeden, geliştirme hızını 10 kat yavaşlatan Kubernetes mikroservis canavarı dağıtıldığını çok fazla gördüm
      “Google böyle yapıyor” dışında bir gerekçe olmadan bu ek yükü taşımaya devam etmek garip
      İyi kullandığımız modüler monolit mimarisi hakkında mutlaka bir yazı yazmalıyım
    • Bulut sağlayıcısına para ödemek zorunda değilsiniz
      Bir hosting şirketinden özel sunucu kiralayıp dilediğiniz gibi kullanabilirsiniz. Yalnız bant genişliği veya aktarım kotası sınırlarına ciddi biçimde takılırsınız
      Bulutun kullanılmasının nedeni, işin içinde çok sayıda çıkar ilişkisinin olması. Örneğin VC’ler ve yatırımcılar bulut şirketlerinde de hisse sahibi ve gerçekte hiç gelmeyecek hayali trafik patlamaları yüzünden yatırımlarının batmasından korkuyorlar
      Bulut satış ekipleri, yatırımcıların kaygılarına dokunmakta ustadır
    • Bir yan projeyi bodrumda barındırmayı düşündüm, ama o zaman elektrik kesintilerine ve ISP arızalarına açık hâle geliyorsunuz
      Seyahatteyken disk bozulursa yapacak bir şey yok; yanlışlıkla kendinizi dışarıda bırakırsanız fallback için seri terminal de yok
      r/homelab insanları gibi kurulum yapılabilir, ama o zaman özellikle kendi zamanımı da hesaba katınca gerçekten para tasarrufu sağlayıp sağlamadığı belirsizleşiyor
      Sonuç olarak bulut sağlayıcılarının ölçek ekonomisi sayesinde oldukça iyi bir anlaşma olduğunu düşünüyorum
    • VM maliyetlerine bakınca yüksek olmasının nedeni çok fazla hesaplama değil, çok yerel diski olan sunuculara ihtiyaç duyulması
      Tuhaf şekilde, bunlardan yalnızca birini ayrı olarak alamıyorsunuz
      Dört adet 20 TB disk ve makul bir CPU ile ne kadar büyük bir iş veya servis çalıştırabileceğinizi hayal edin
      Bulut sağlayıcısından böyle bir yapılandırma almak kolay değil
  • “Erken dönem web topluluğu bunun kötü bir fikir olduğunu çabuk öğrendi ve PHP gibi teknolojiler icat etti” kısmında, teknik olarak çekirdek teknoloji mod_php idi
    PHP’nin kendisi çalıştırılma biçimi açısından Perl’den farklı değildi; ama mod_perl ile karşılaştırıldığında mod_php’nin tasarım tercihleri sayesinde PHP betikleri sunucuya öylece atıldığında hızlı çalışıyordu, mod_perl’i çalıştırmak içinse biraz düşünce ve sihir gerekiyordu

    • O dönemde bir arkadaşımla, sonradan öğrenim yönetim sistemi denecek türden bir şey geliştiriyorduk
      İçerik yönetimi, ödev yükleme, etkinlik takvimi, not yönetimi, gerçek zamanlı sohbet ve forumlar vardı; hepsi CGI üzerinde saf C idi ve üzerinde çalışmak cehennem gibiydi
      PHP’yi öğrendiğim gün neredeyse ağlayacaktım; çünkü RFC okuyarak veya HTTP’yi tersine mühendislik ederek sıfırdan zorlukla yazdığımız her şey PHP’de basit bir fonksiyon çağrısıydı
      Artık aksak urlencode uygulamalarını debug etmek ya da HTTP başlığındaki tuhaf bir carriage return yüzünden bir günü çöpe atmak zorunda değildik
    • Doğru, ama mod_php PHP ekosistemine erken eklendi ve hızla varsayılan dağıtım biçimi hâline geldi
      Apache modülünün ilk sürümünün 1996’da PHP/FI Version 2.0 için olduğunu sanıyorum: https://www.php.net/manual/phpfi2.php#module
  • cgi-bin'in veritabanına erişmesi gerekiyorsa, süreç her başladığında bağlantı açması gerekir
    FastCGI gibi kodu bellekte tutmak yalnızca başlatma süresi maliyetinden kaçınmak için değil, veritabanı bağlantı havuzu ya da en azından iş parçacığı başına kalıcı bağlantılar bulundurabilmek içindir

    • Ölçek büyüdüğünde bağlantı sayısı yüzünden veritabanı zorlanır
      “Python tek iş parçacıklı, o yüzden çok sayıda çalıştıralım” ile “Python yavaş, o yüzden çok sayıda çalıştıralım” aynı anda yapıldığında böyle olmuştu
      Ölçek büyüdükçe sonunda pgbouncer gibi Python dışındaki paylaşımlı bağlantı havuzu ve bolca ayarla, veritabanını öldürmeden yükü kaldırır hale getirmek gerekir
      Elbette ardından, belli ölçüde performans veren çok iş parçacıklı bir dille yeniden implemente edince her şey tekrar oldukça basitleşti
    • Bu yüzden CGI sonunda istekler arasında bir miktar durum tutan bir modele evrildi
    • Bunu ele almanın standart bir yolu da vardı
      Fiilen proxy rolü gören ayrı bir daemon çalıştırmak şeklindeydi
      TCP/IP yerine Unix soketi kullanınca bağlantı maliyeti görece düşer
    • UDP kullanılabilir
  • Bu donanımda bir hello world uygulamasının saniyede 2.400 istek işlemesi biraz kötü değil mi
    Performanstan vazgeçip tam olarak ne kazanıldığını da bilmiyorum. Kodun daha basit hale geldiği de yok

    • Saniyede 2.000 isteğin üstüne çıkmanız gerektiğinde kötü bir rakamdır
      Böyle siteler toplamın yalnızca bir kısmıdır
    • Harika değil ama birçok kullanım senaryosu için yeterli
      HN trafik bombardımanına da dayanabilir gibi
  • Dün de tartışılmıştı: https://news.ycombinator.com/item?id=44464272

  • Şirkette bazen hızlıca yapılan dahili web uygulamaları için hâlâ cgi-bin dizini sunuyoruz
    Basit tutulursa kullanışlı oluyor
    CGI demek, HTTP/1.0'ı doğrudan stdout'a print etmek zorundasınız demek değil
    Örneğin Python'ın yerleşik wsgiref.handlers.CGIHandler'ını kullanırsanız herhangi bir WSGI uygulamasını CGI betiği olarak çalıştırabilirsiniz
    import wsgiref.handlers, flask
    app = flask.Flask(name)
    wsgiref.handlers.CGIHandler().run(app)
    Betikleri uwsgi ve onun CGI eklentisi[1] ile çalıştırıyoruz
    mod_cgi yüzünden Apache ya da lighttpd çalıştırmaktan daha basit ve esnek olduğunu düşünüyoruz
    uwsgi bir systemd birimi olarak çalıştığı için systemd'nin sertleştirme ve sandbox özelliklerinin tamamından da yararlanabiliyoruz
    uwsgi'nin CGI işlemede mod_cgi'de olmayan kullanışlı yanı, belirli dosya türleri için kullanılacak yorumlayıcıyı belirtebilmeniz
    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 bayta kadar geçen süre 250~350 ms ve bizim kullanımımız için kabul edilebilir
    [1]: https://uwsgi-docs.readthedocs.io/en/latest/CGI.html

    • İyi bilgi; wsgiref.handlers.CGIHandler hâlâ kullanımdan kaldırılacak gibi görünmüyor
  • Yakın zamanda bir yan projede Apache kullandım; nedenlerden biri .htaccess özelliğiydi ve benzer bir konuşma yaptık
    .htaccess dosyasını herhangi bir yere koyduğunuzda Apache bunu her istekte ek sunucu yapılandırması olarak okuyabilir: https://httpd.apache.org/docs/2.4/howto/htaccess.html
    Bundan kaçınmanın büyük nedeni performanstı. Her istekte ek disk erişimi gerekiyordu ve mümkünse bunu ana yapılandırma dosyasına koymak her zaman daha iyiydi
    Ama artık çoğu sunucuda SSD var ve Linux'un dosya sistemi önbelleği için kullanabileceği boş RAM'e sahip olma olasılığı da yüksek
    Elbette Apache yapılandırmayı bir kez değil, her istekte ayrıştırmak zorunda olduğundan performans hâlâ biraz kötüleşir
    Yine de günümüzde çoğu sunucu CPU'sunun daha güçlü olduğu düşünülürse, birçok kullanım senaryosunda bu göze alınabilir
    Yan proje çok erken bir sürümde ama şimdiden kullanılıyor: https://github.com/StaticPatch/StaticPatch/tree/main

    • Rasmus Lerdorf'tan alıntıyla:
      “Ben gerçek bir programcı değilim. Çalışana kadar bir şeyleri birbirine ekler, sonra devam ederim. Gerçek programcılar ‘Evet, çalışıyor ama orada burada bellek sızıntıları var. Düzeltmemiz gerekmez mi?’ derdi. Ben ise Apache'yi her 10 istekte bir yeniden başlatırım.”
      PHP o zamandan bu yana çok yol kat etti, ama bunun büyük bir kısmı ilk hataları düzeltme süreciydi
      “PHP 8'in çok daha iyi olmasının nedeni, içinde benim kodumun çok daha az olması.”
    • Apache'nin neden dosya sistemini doğrudan izlemediğini anlamıyorum
      Bu seçim yüzünden HTTP isteklerinin %99,99'u gereksiz disk okumalarıyla yavaşlıyor gibi geliyor
  • Hızlı prototipleme iş akışının bir parçası olarak bunu daha fazla düşündüm
    Modern JIT dillerinin, FastCGI modeline geçilmediği sürece başlangıç süresinin büyük ölçüde import’lar tarafından belirleneceğini düşünüyorum
    Yerel betikler için h2o web sunucusunu kullanmaya başlayınca bu aklıma geldi; mruby ve FastCGI handler ile yapılandırma dosyaları temiz ve hızlı yazılabiliyor, performansı da çok yüksek: https://h2o.examp1e.net/configure/fastcgi_directives.html
    Bir başka işe yaradığı yer de müşterilerin yerel yazılımı kendi kodlarıyla genişletmesini sağladığınız durumlar
    Örneğin bir yapay zeka aracını genişletmek için MCP kullandırmak yerine, belirli bir istek yapısını CGI olarak uygulamalarını isteyebilirsiniz

    • Son kullanıcı ortamında CGI programları için bir MCP frontend fena fikir değil
      MCP hizmetinin kendisi de CGI ile uygulanabilir mi diye merak ediyorum
      Bir MCP framework’ü, işlevleri her iki çalışma modunu da destekleyen bir program biçiminde de sunabilir
      Spesifikasyonu biraz kurcalamam gerekecek
    • FastCGI, CGI’nin avantajlarının neredeyse tamamını kaybetme eğiliminde
  • Benim için inetd doğrudan CGI demekti
    Bu sayede internet çok daha eğlenceli hale geldi
    Doğrudan inetd ile birkaç shell betiği barındırdım; tamamen Bash ile yazılmış bir HTTP sunucum da vardı
    O VPS uzun zaman önce kayboldu, o dönemde sürüm kontrolü de kullanmıyordum
    Onu yazdığım dizüstü bilgisayar da yok oldu
    Yine de gerçekten çok eğlenceliydi
    Dağıtım Makefile + scp kadar kolaydı; test ise birkaç netcat ve grep’i bir araya getiren başka bir Bash betiğiydi
    Ne güzel günlerdi