- Dengan pemrograman CGI, pemrosesan lebih dari 200 juta permintaan web per hari juga dimungkinkan
- Peningkatan kinerja perangkat keras belakangan ini sangat mengurangi kelemahan pendekatan CGI
- Program CGI yang memanfaatkan Go dan SQLite menunjukkan kinerja luar biasa pada CPU 16-thread
- CGI menyediakan struktur yang sangat cocok untuk memanfaatkan banyak inti CPU
- Berkat teknologi modern, cara lama membangun aplikasi web pun masih cukup layak secara praktis
Masa lalu dan masa kini CGI
- Pada akhir 1990-an, penulis mulai mengembangkan web dengan CGI dan saat itu menggunakan sistem seperti NewsPro
- CGI menimbulkan overhead tinggi karena untuk setiap permintaan web harus berulang kali menjalankan dan mengakhiri proses baru
- Karena alasan ini, teknologi pengganti yang lebih efisien seperti PHP dan FastCGI dikembangkan
Perkembangan kinerja perangkat keras
- Selama lebih dari 20 tahun terakhir, kecepatan dan kinerja komputer meningkat drastis
- Pada tahun 2020, penulis memanfaatkan alat yang dikembangkan dengan Go dan Rust (
ripgrep dan lainnya), lalu menemukan kembali sisi praktis dari pendekatan berbasis eksekusi proses
Keunggulan pendekatan CGI modern
- Jika CGI diimplementasikan dengan bahasa yang cepat dijalankan seperti Go dan Rust, sebagian besar kelemahan CGI lama dapat diatasi
- Program CGI berjalan sebagai proses terpisah untuk setiap permintaan, sehingga sangat optimal untuk memanfaatkan CPU multicore
- Sebagai contoh, di lingkungan 16-thread terkonfirmasi kemungkinan menangani lebih dari 2400 permintaan/detik = 200 juta+ permintaan/hari
- Server besar dapat menyediakan lebih dari 384 thread CPU
Insight tentang budaya pengembangan
- Kini, dengan adopsi bahasa seperti Go dan Rust, pendekatan CGI ala 1990-an bisa kembali memiliki makna
- Namun, ini tetap bukan pendekatan yang cocok untuk semua lingkungan, dan tidak direkomendasikan sebagai arus utama
- Poin pentingnya adalah, pada saat ini telah dibuktikan secara eksperimental bahwa CGI bukan lagi solusi yang seefisien dulu dianggap tidak mungkin
Kesimpulan
- Dengan perangkat keras modern dan dukungan bahasa yang cepat, pemrograman CGI menunjukkan kinerja yang tak bisa dibandingkan dengan masa lalu
- Sebagai contoh yang dapat memaksimalkan keunggulan multiproses, hal ini menawarkan sudut pandang menarik bagi para pengembang web
1 komentar
Komentar Hacker News
Akhir-akhir ini, bahkan dengan Python pun CGI terasa cukup cepat
Kalau skrip CGI menghabiskan 400 milidetik CPU saat startup, dengan server 64 core tetap bisa menangani 160 request per detik, atau 14 juta trafik per hari per server
Artinya, bahkan trafik harian ratusan juta request pun (tidak termasuk aset statis) startup proses CGI bukanlah bottleneck
Dulu saya menganggap teknologi seperti ini itu "teknologi yang sangat stabil sampai membosankan", jadi selalu ada di standard library Python, tetapi maintainer Python belakangan justru cenderung negatif terhadap stabilitas dan kompatibilitas mundur
Karena itu, modul yang terlalu 'membosankan dan stabil' sedang dihapus dari standard library, dan modul
cgimemang sudah dihapus pada versi 3.13Mungkin karena saya sudah hampir 25 tahun terbiasa memakai Python untuk prototyping, tapi sekarang jadi agak menyesal
Sekarang perasaannya bimbang antara JS dan Lua
Tautan penjelasan resmi soal penghapusan cgi: PEP 594 cgi
Dari sana tersambung ke PEP 206 yang ditulis tahun 2000 (25 tahun lalu), dan bahkan saat itu sudah dijelaskan bahwa "paket cgi desainnya kurang bagus dan sulit disentuh"
Di repositori jackrosenthal/legacy-cgi bisa dilihat drop-in replacement yang menggantikan modul standard library apa adanya
Developer Python hanya menghapus modul yang bernama cgi
Implementasi skrip CGI masih didukung lewat
CGIHTTPRequestHandlerdi modulhttp.serverJuga diingatkan bahwa modul cgi aslinya memang hanya berisi beberapa fungsi untuk parsing data form HTML
Saya paham kritik terhadap dihapusnya modul cgi dari standard library Python, tetapi JS yang sering disebut sebagai alternatif bahkan bukan standard library sama sekali
Juga ditunjukkan bahwa Lua pun tidak punya modul CGI di stdlib
Secara pribadi saya lebih suka PHP atau JS
Dalam kasus seperti ini, JIT sudah tersedia langsung di dalam kotaknya jadi lebih nyaman
Saya sudah memakai Python sejak 1.6, tetapi kebanyakan hanya untuk scripting OS
Dulu saya punya pengalaman menghubungkan Tcl sebagai modul Apache atau IIS sambil terus-terusan menulis ulang modul dalam C (1999~2003)
Kalau skrip CGI memakai 400 milidetik CPU, maka waktu respons endpoint itu minimal juga akan sebesar itu, jadi berdampak ke usability
Baru-baru ini saya memasang binary golang, rabbitmq, redis, dan MySQL di mini server seharga 350 dolar, lalu secara berkelanjutan menangani 5.000 req/s di server yang sama
Dalam 24 jam berarti kapasitasnya 400 juta request
Benar-benar terasa betapa hebatnya tool gratis zaman sekarang
Meski begitu, saya tetap merasa biaya cloud terlalu mahal
Tentu ini bukan perbandingan 1:1, tetapi ada kepuasan besar karena bisa melakukan development dan tuning sendiri langsung dari server di ruang bawah tanah rumah
Ada juga kasus di mana kecepatan development jadi 10 kali lebih lambat karena memakai tumpukan microservice berbasis Kubernetes
Banyak orang tidak sadar bahwa server bukan mesin yang cuma bisa menangani 1 request per detik
Kenyataannya, banyak yang membayar overhead berlebihan hanya karena ikut-ikutan Google
Saya sendiri jadi kepikiran harus menulis artikel soal arsitektur 'modular monolith' yang cocok untuk tim kami
Saya pernah ingin self-host side project di rumah, tetapi risikonya besar: listrik padam, ISP downtime, tidak bisa akses jarak jauh, hard drive rusak, dan sebagainya
Pada akhirnya, kalau waktu saya sendiri ikut dihitung, keuntungan ekonominya jadi meragukan
Layanan cloud bisa memanfaatkan skala ekonomi, jadi dalam praktiknya tetap pilihan yang masuk akal
Tidak harus cloud, bisa juga menyewa dedicated server dari hosting provider
Tentu ada batas bandwidth/trafik
Alasan cloud jadi arus utama adalah karena VC dan investor punya kepemilikan di perusahaan-perusahaan itu, atau karena ada kecemasan bahwa "trafik tak terbatas bisa tiba-tiba meledak"
Tenaga penjualan cloud sangat lihai memanfaatkan kecemasan investor itu
Bukan berarti semua orang harus memakai cloud
Dalam layanan nyata, mahalnya biaya VM bukan karena butuh komputasi superkencang, tetapi karena perlu local disk berkapasitas sangat besar
Tidak perlu kemampuan komputasi tinggi; dengan empat hard disk 20TB dan CPU yang lumayan saja sudah bisa membayangkan layanan yang hebat
Di cloud hampir mustahil menemukan kombinasi seperti ini
Kalau di cgi-bin perlu akses ke DB, merepotkan karena setiap kali proses harus membuat koneksi DB baru
Jika kodenya berjalan di memori (seperti fastcgi), bukan hanya waktu startup yang berkurang, tetapi juga memungkinkan connection pool DB atau koneksi permanen per thread
Saat dijalankan dalam skala besar, jumlah koneksi DB bisa jadi terlalu banyak dan memberatkan DB
Karena alasan seperti "python single-threaded jadi perlu banyak proses" dan "python lambat jadi perlu lebih banyak proses", akhirnya menjalankan banyak proses
Pada akhirnya connection pool bersama dipisah di luar proses python sendiri (misalnya pg bouncer), dan perlu berbagai tuning
Pada tahap akhir, pernah ada pengalaman menulis ulang dengan bahasa yang lebih mudah dikendalikan (mendukung multithreading dan performanya lebih baik), lalu semuanya jadi jauh lebih sederhana
Karena itu CGI pada akhirnya berkembang ke model yang menyimpan informasi antar-request (seperti fastcgi)
Secara tradisional, orang juga menjalankan daemon terpisah sebagai proxy, dan kalau koneksinya memakai Unix socket jauh lebih efisien daripada TCP/IP
Ada yang menyarankan memakai UDP
Bagi saya, inetd itu sendiri sudah seperti CGI
Karena itu internet terasa jauh lebih menyenangkan
Ada masa ketika saya benar-benar menjalankan berbagai shell script lewat inetd, bahkan HTTP yang ditulis hanya dengan Bash
VPS lama, laptop tanpa backup atau version control memang sudah hilang, tetapi itu kenangan yang menyenangkan
Deployment juga sederhana dengan Makefile + scp, dan testing pun bisa dilakukan lewat skrip Bash yang ditulis memakai netcat dan grep
Benar-benar terasa seperti hidup di zaman yang enak
Kesan saya, hello world app yang hanya mencapai 2400 rps (request per second) itu tidak terlalu mengesankan menurut standar hardware saat ini
Kodenya juga tidak jadi lebih sederhana, jadi saya bertanya-tanya demi apa performa dikorbankan
Kalau tidak perlu menangani lebih dari 2000 rps, ya tidak ada masalah
Intinya, situs yang benar-benar butuh trafik sebesar itu jumlahnya sangat sedikit
Secara angka memang tidak terlalu tinggi, tetapi dalam praktiknya sudah cukup untuk banyak lingkungan
Bahkan cukup kuat untuk menahan 'hug of death' yang sering dibicarakan developer HN, yaitu lonjakan masuk mendadak pada momen tertentu
Di perusahaan kami, sampai sekarang masih memakai cara cepat menjalankan web app internal sederhana lewat direktori cgi-bin
Kalau dipakai secara sederhana, efisiensi pengembangannya sangat bagus
Bahkan dengan cgi pun tidak perlu
printhttp/1.0 secara langsung, dan dengan memakaiwsgiref.handlers.CGIHandlerdari Python, aplikasi wsgi apa pun bisa dijalankan sebagai skrip cgiContoh kode Flask juga sesederhana berikut
Di praktik kerja, kami menjalankan skrip lewat plugin cgi milik uwsgi
Rasanya jauh lebih sederhana dan fleksibel daripada menjalankan mod_cgi di Apache atau lighttpd
Karena uwsgi berjalan sebagai unit sistem, semua hardening dan sandboxing dari systemd juga bisa dipakai, yang merupakan keunggulan lain
Selain itu, dalam penanganan cgi oleh uwsgi, interpreter bisa ditentukan per tipe file
Waktu sampai byte pertama terkirim sekitar 250~350ms, dan untuk kebutuhan kami itu masih sangat bisa diterima
Dokumentasi uwsgi tentang cgi
Fakta bahwa
wsgiref.handlers.CGIHandlermasih belum deprecated itu informasi yang bergunaThread terkait yang dibahas kemarin tautan
Belakangan saat memakai Apache untuk side project, saya merasa fitur
.htaccessbergunaCukup taruh file
.htaccessdi direktori mana pun, dan konfigurasi server tambahan akan dimuat untuk setiap request individualDokumentasi resmi htaccess
Dulu disarankan menghindari
.htaccesskarena overhead performa akibat akses disk di setiap request, dan sebisa mungkin menggabungkannya ke konfigurasi utamaTetapi sekarang SSD dan RAM sudah cukup memadai, jadi meskipun tentu ada sedikit kerugian performa, CPU modern cukup bagus sehingga bagi kebanyakan kasus itu bisa diabaikan
[Proyek saya StaticPatch][https://github.com/StaticPatch/StaticPatch/tree/main] juga sudah menerapkannya dan sedang dipakai
Kutipan terkenal dari pencipta PHP, Rasmus Lerdorf
"Saya bukan programmer sungguhan, saya cuma membuatnya bekerja lalu lanjut. Programmer sungguhan akan bilang, 'ini bocor memorinya parah, harus diperbaiki'. Saya cuma me-restart apache setiap 10 request"
Setelah itu PHP menempuh perjalanan panjang, mengatasi kesalahan-kesalahan awal dan berkembang jauh
Ada juga kisah bahwa ia pernah berkata, "PHP 8 makin bagus kalau kode saya semakin sedikit"
Apache seharusnya bisa memantau file system lalu membacanya hanya saat ada perubahan; saya tidak paham kenapa harus memaksa akses disk yang tidak perlu di setiap request
Akibatnya 99,99% request http menjadi lebih lambat
Belakangan saya mempertimbangkan struktur seperti ini untuk prototyping cepat dalam workflow
Bahasa JIT akan mengalami bottleneck pada import kalau bukan dalam bentuk fastcgi
Web server h2o yang pernah saya pakai punya file konfigurasi handler mruby dan fast-cgi yang sederhana, jadi sangat pas untuk pekerjaan skrip lokal
Dokumentasi fastcgi h2o
Keuntungan lainnya, ini juga berguna saat ingin memungkinkan pelanggan menambahkan custom code sendiri untuk memperluas software lokal
Misalnya, sebelumnya perlu memakai MCP untuk ekstensi, tetapi sekarang cukup mengimplementasikan request terstruktur dengan CGI
Untuk lingkungan end-user, menghubungkan program CGI sebagai front MCP juga tampak seperti ide yang layak dipertimbangkan
Layanan MCP sendiri pun tampaknya cukup mungkin diimplementasikan dengan CGI
Rasanya perlu melihat spesifikasinya lebih dalam
Ada pertanyaan apakah fastcgi membuat hampir semua kelebihan cgi justru hilang
Dulu saya pernah langsung memakai kombinasi program C dan CGI
Saat itu belum ada lebih dari 100 core atau RAM besar, dan semuanya berjalan bahkan dengan memori maksimal sekitar 1GB
Kalau memikirkan apa yang dulu bisa dilakukan, saya yakin sekarang justru akan jauh lebih mudah
Setelah kebutuhan load balancing muncul, skalanya memang jadi sulit dikembangkan, tetapi sebelum itu pendekatan tersebut bekerja cukup baik
Sebagai catatan, front dan backoffice waktu itu berupa dua executable terpisah