- वेब के शुरुआती दौर में व्यापक रूप से इस्तेमाल होने वाले CGI programs आज के हार्डवेयर पर भी उच्च performance दे सकते हैं, यह प्रयोग से पुष्टि की गई
- CGI हर request को अलग process में handle करता है, इसलिए memory management अपने-आप हो जाता है और deployment सरल रहता है
- Benchmark नतीजों से साबित हुआ कि साधारण 16-thread CPU server पर भी प्रति सेकंड 2400 से अधिक, यानी रोज़ 20 करोड़ से अधिक requests process करना संभव है
- Go और SQLite से लिखा गया guestbook.cgi example code और Dockerfile open source के रूप में जारी किया गया
- CGI आज भले आम तौर पर इस्तेमाल न होता हो, फिर भी यह अब भी व्यावहारिक और आधुनिक विकल्प हो सकता है, यह दिखाया गया
CGI programs और उनका काम करने का तरीका
- 2000 के दशक की शुरुआत में CGI(Common Gateway Interface) programs dynamic websites बनाने का मुख्य तरीका थे
- इनमें से अधिकांश Perl या C language में लिखे जाते थे, और performance बढ़ाने के लिए कभी-कभी C चुनी जाती थी
- CGI का concept सरल है, लेकिन शक्तिशाली है
- web server environment variables में request metadata (HTTP headers, query आदि) set करता है
- अलग process बनाकर CGI program चलाता है
- request body को stdin के जरिए भेजता है
- program के stdout को HTTP response के रूप में capture करता है
- stderr output को server error log में भेजता है
- program के request पूरा करते ही process समाप्त हो जाता है, इसलिए file descriptors और memory अपने-आप मुक्त हो जाते हैं
- developer के नज़रिए से नया version deploy करना भी cgi-bin/ directory में सिर्फ file copy करने जितना आसान था
Hug of death(ट्रैफ़िक विस्फोट)
- 2000 के दशक की शुरुआत में अधिकतर web servers में 1~2 CPU और 1~4GB memory आम बात थी
- Apache web server की ऐसी संरचना, जिसमें हर connection पर httpd process fork होता था, के कारण अधिक connections पर memory की मांग बढ़ जाती थी
- 100 से ज़्यादा simultaneous connections संभालना मुश्किल था, और किसी प्रसिद्ध site पर सिर्फ link लगने से भी server आसानी से overload हो जाता था
- ( Slashdot Effect : उस समय मशहूर Slashdot पर link आते ही ट्रैफ़िक उमड़ पड़ता था। यह आज Hacker News के top पर आने जैसा है)
आधुनिक server environment में CGI
- आज 384 CPU threads वाले servers भी मौजूद हैं, और अपेक्षाकृत छोटे VM में भी 16 CPU मिल सकते हैं
- CPU और memory performance में बहुत बड़ा सुधार हुआ है
- CGI programs अलग process आधारित होते हैं, इसलिए multi-core का स्वाभाविक रूप से उपयोग कर सकते हैं
- इसी वजह से आधुनिक हार्डवेयर पर CGI programs कितने तेज़ हैं, यह देखने के लिए सीधे benchmark test किए गए
- प्रयोग AMD 3700X(16-thread) server पर किया गया
Benchmark के मुख्य नतीजे
- एक साधारण CGI program को Apache और Go
net/http server दोनों environments में test किया गया
-
guestbook.cgi program का विवरण
- HTTP load generation tool
plow का उपयोग करके 16 connections के साथ 1 लाख requests चलाई गईं
- साधारण hardware पर भी प्रति सेकंड 2,400 से अधिक, यानी रोज़ 20 करोड़ से अधिक requests process की जा सकती हैं
- CGI आज मुख्यधारा नहीं है, फिर भी इसे वास्तविक services में इस्तेमाल किया जा सकता है
-
Apache environment में write benchmark
- प्रति सेकंड लगभग 2468 requests process हुईं, औसत 6.47ms response latency रही
- 1 लाख POST requests सिर्फ 40.5 सेकंड में process हुईं
- अधिकतर requests 7ms के भीतर respond हुईं, और बहुत कम 100ms से ऊपर गईं
- व्यावहारिक रूप से उच्च write throughput साबित हुआ
-
Apache environment में read benchmark
- प्रति सेकंड लगभग 1959 requests process हुईं, औसत 8.16ms response latency रही
- 1 लाख GET requests 51 सेकंड में process हुईं
- आधे से अधिक requests 8ms के भीतर थीं, और अधिकतम latency भी सिर्फ 31ms रही
- read performance भी काफ़ी अच्छी रही
-
Go net/http environment में write benchmark
- प्रति सेकंड लगभग 2742 requests process हुईं, औसत 5.83ms response latency रही
- 1 लाख POST requests सिर्फ 36.4 सेकंड में process हुईं
- throughput औसतन 2,742 RPS और औसत latency 5.8ms रही, जो आँकड़ों में Apache से बेहतर थी
- 95% से अधिक requests 6ms के भीतर process हुईं
- Go environment में CGI ने भी पर्याप्त production-grade performance दिखाई
-
Go net/http environment में read benchmark
- प्रति सेकंड लगभग 2469 requests process हुईं, औसत 6.47ms response latency रही
- 1 लाख GET requests 40.4 सेकंड में process हुईं
- अधिकतर requests 7ms के भीतर serve की जा सकीं
- read throughput और response speed, दोनों में Apache के बराबर या बेहतर प्रदर्शन मिला
निष्कर्ष और links
- CGI programs के पास नवीनतम hardware पर बहुत तेज़ concurrency, सरल deployment, और operating system द्वारा automatic resource cleanup जैसे फायदे हैं
- आधुनिक frameworks की तुलना में यह बेहद सरल है, लेकिन एक निश्चित पैमाने की services में आज भी व्यावहारिक रूप से इस्तेमाल हो सकता है
- guestbook example और benchmark experiment data नीचे GitHub पर public है
https://github.com/Jacob2161/cgi-bin
4 टिप्पणियां
अरे.. क्या अब फिर से
cgiइस्तेमाल करने की नौबत आ रही है?? hahaवाह..
cgiको इस्तेमाल किए कितना ज़माना हो गया..लगता है 7/7 तारीख़ के अनुसार अपडेट की गई सामग्री है।
Serving a half billion requests per day with Rust + CGI
5 अरब requests...
Hacker News राय
1990 के दशक में भी C में लिखे गए CGI प्रोग्राम सच में बहुत तेज़ चलते थे, यह माहौल याद है, लेकिन यह भी मानना होगा कि उनमें errors बहुत आते थे; लेख में बताए गए Go प्रोग्राम या Nim जैसी आधुनिक भाषाएँ भी, जब तक database connection न हो, localhost पर बेहद तेज़ और low-latency महसूस होती हैं, मानो CLI utility में fork & exec का इस्तेमाल हो रहा हो, और network latency की तुलना में इसकी लागत लगभग नगण्य थी
लेकिन यह भी कहा गया कि कुछ तकनीकों की आदत लग जाना आसान है; उदाहरण के लिए, Python interpreter जैसी high startup cost वाली भाषा की आदत पड़ जाए तो फिर multishot या persistent model की ज़रूरत महसूस होने लगती है
शुरुआती HTTP का one-shot model उस समस्या से निकला था कि FTP server के पास इतने memory resources नहीं थे कि सैकड़ों idle login sessions लंबे समय तक बनाए रख सके
CGI में pre-forking (जो latency छिपा सकता है) और Rust जैसी safe language को मिलाकर बेहतरीन system design संभव हो सकता है; TLS termination को multithreaded web server (या CloudFront जैसी layer) में संभाला जा सकता है, इसलिए यह काफ़ी सुविधाजनक है
CGI के दौर से development शुरू करने के कारण, कम समय तक चलने वाले subprocesses चलाने को लेकर गहरी नापसंदगी बन गई थी
यह पृष्ठभूमि बताई गई कि PHP और FastCGI वेब request पर हर बार नया process बनाने की performance समस्या से निकलने के लिए बनाए गए थे
हाल के hardware विकास की वजह से अब समझ आया कि process startup cost वास्तव में इतनी बड़ी समस्या नहीं है
यह benchmark प्रति सेकंड 2000 requests संभाल सकता है, और अगर कुछ सौ requests प्रति सेकंड भी संभालने हों तो कई instances में scale करना आधुनिक माहौल में आसान है
AWS Lambda को CGI model का पुनर्जन्म कहना उचित लगा, और इसे काफ़ी सही तुलना माना गया
अगर CGI script को statically linked C binary के रूप में, size का ध्यान रखते हुए deploy किया गया होता, तो शायद निराशा कम होती
CGI low-load environment में पैसे और performance दोनों के हिसाब से बहुत भारी नहीं था
Go आने से पहले 2000 के दशक में CGI प्रोग्राम C/C++ में बनाना safety और development difficulty दोनों के लिहाज़ से कठिन था
आज के servers में 384 CPU threads तक होते हैं, और छोटे VM में भी 16 CPU होना आम है
ऐसे hardware पर Kestrel के साथ development करें तो दिन में खरबों requests संभालना भी सहज हो सकता है
PHP जैसा development अनुभव string interpolation operator से दिया जा सकता है
LINQ और String.Join() की मदद से HTML tables और nested elements को आसानी से template किया जा सकता है
असली मुश्किल यह जानना है कि MVC/Blazor/EF जैसे ecosystem की landmines से कैसे बचा जाए
पूरे program को एक single top-level file में CLI से चलाना भी संभव है, लेकिन अगर "Minimal APIs" keyword न पता हो तो ग़लत documentation की भूलभुलैया में फँसना आसान है
CGI का एक फ़ायदा यह है कि multi-tenant environment में isolation primitives अलग से बनाने की ज़रूरत नहीं पड़ती
rlimitसे लंबे समय तक चलने वाली requests को ज़बरदस्ती terminate किया जा सकता हैcgroupका उपयोग करके tenant के हिसाब से memory, CPU, disk/network IO का निष्पक्ष allocation किया जा सकता हैCGI scripts की वजह से perl को fast startup time के लिए optimize किया गया था
time perl -e ''चलाने पर perl 5ms, python3 33ms, और ruby 77ms लेता है, जिससे perl का तेज़ startup time दिखता है#!/bin/tcc -runशैली की scripts, perl से 1.3 गुना तेज़ बताई गईंapache tomcat 11 का उपयोग करने पर, बस
.jspफ़ाइल या पूरा java servlet application (.war) ssh से upload कर दें तो वह सीधे चलने लगता हैएक shared JVM से अधिकतम performance हासिल की जा सकती है
DB connection pool, cache आदि भी applications के बीच साझा किए जा सकते हैं
यह सच में प्रभावशाली अनुभव है
यह वास्तविक usage pattern पर निर्भर करता है
बड़े services के लिए यह शानदार है, लेकिन अगर 50 छोटे applications हों और हर एक में दिन भर में कुछ सौ requests ही आएँ, तो Tomcat का memory overhead CGI script आधारित Apache/Nginx की तुलना में बहुत बड़ा लगता है
फ़ाइल कॉपी करके deploy करने वाले दिन याद आते हैं
deployment इतना जटिल क्यों हो गया, इस पर अफ़सोस जताया गया
अभी भी Jetty के साथ backend webapps मज़े से चलाने का अनुभव साझा किया गया
Tomcat/Jakarta EE/JSP stack उम्मीद से ज़्यादा मज़बूत लगा
PHP की तरह HTML और code को मिलाकर लिखा जा सकता है, और pure Java routes भी संभव हैं
Websockets support है, single-process multithreaded model होने से real-time communication में भी फ़ायदा है
ज़रूरत पड़ने पर requests के बीच data share किया जा सकता है, जबकि JSP code मूल रूप से request scope तक सीमित रहता है
deployment बहुत आसान है; webapps directory में नई फ़ाइल upload करते ही Tomcat अपने-आप नया app load कर लेता है और पुराने app को unload कर देता है
एक कमी यह है कि classloader leak की वजह से garbage collection विफल हो सकता है, जो single-process model की स्वाभाविक समस्या है
apache requests को visualize करने वाला टूल ibrahimdiallo.com/reqvis बनाया गया
आजकल complex architectures की ओर बढ़ना संदिग्ध लगने लगा; शायद अच्छे hardware के साथ पुरानी technologies भी काफ़ी हो सकती हैं
लाखों लोगों को real-time stock quotes देने वाली system design के सवाल पर पहले Kafka, pubsub जैसी complex stream structures दिमाग़ में आईं, लेकिन अंत में server पर static files रखने जैसी simple approach पर भी विचार हुआ
इस तरीके की वास्तविक operating cost कैसी होगी, यह जानने की उत्सुकता है
यह serverless architecture जैसा है, लेकिन उससे कहीं ज़्यादा simple और सस्ता
इस तरह की पारंपरिक संरचना पर फिर से विचार करने के बजाय सिर्फ़ "serverless functions" नाम का नया paradigm बना देने पर अफ़सोस जताया गया
cgiतो फिर भी समझ आता है, लेकिनjspपर लोगों की प्रतिक्रिया काफ़ी चौंकाने वाली है lolक्या
jspसच में अब उस हद तक का प्राचीन अवशेष बन चुका है?