7 पॉइंट द्वारा GN⁺ 2025-07-07 | 4 टिप्पणियां | WhatsApp पर शेयर करें
  • वेब के शुरुआती दौर में व्यापक रूप से इस्तेमाल होने वाले 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 टिप्पणियां

 
kansm 2025-07-09

अरे.. क्या अब फिर से cgi इस्तेमाल करने की नौबत आ रही है?? haha
वाह.. cgi को इस्तेमाल किए कितना ज़माना हो गया..

 
tujuc 2025-07-08

लगता है 7/7 तारीख़ के अनुसार अपडेट की गई सामग्री है।

Serving a half billion requests per day with Rust + CGI

5 अरब requests...

 
GN⁺ 2025-07-07
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) में संभाला जा सकता है, इसलिए यह काफ़ी सुविधाजनक है

      • state नहीं बचता, core dump और debug करना बहुत आसान होता है, और मुख्यतः linear request model के कारण scaling भी सरल हो सकती है
      • stdin से पढ़ना और stdout में लिखना ही काफ़ी है, इस सादगी की तारीफ़ की गई; Websockets जटिलता थोड़ा बढ़ाते हैं, लेकिन चिंता की बात नहीं
      • Java के उभार के साथ fork() की लागत और C के ख़तरों से बचने के लिए application server की ओर तेज़ी से बदलाव हुआ था, और अब फिर से simplicity की ओर लौटा जा सकता है
      • Rust पसंद न होने के बावजूद, अगर इस तरह का web backend code आसानी से लिखा जा सके, तो node/js, php, python developers के लिए भी यह आकर्षक हो सकता है
  • 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 किया गया होता, तो शायद निराशा कम होती

      • PHP interpreter, अलग-अलग libraries की loading, file parsing आदि के कारण dynamically linked process की startup cost कहीं ज़्यादा होती है
      • Go का उपयोग ऐसा तरीका है जो 25 साल पहले भी काफ़ी प्रतिस्पर्धी हो सकता था
      • SQLite database खोलना performance के लिहाज़ से socket को context switch के ज़रिए पास करने के लगभग बराबर है, और remote mysql connection की तुलना में बहुत तेज़ है
      • FastCGI आज भी नए applications के लिए बेहतरीन विकल्प है
    • CGI low-load environment में पैसे और performance दोनों के हिसाब से बहुत भारी नहीं था

      • high-load स्थिति में FastCGI जैसे लगातार चलने वाले process ज़्यादा फ़ायदेमंद होते हैं
      • CGI भी 2,000 rps तक संभाल सकता है, लेकिन FastCGI उससे कहीं अधिक performance दे सकता है
      • अलग server process जोड़ना और upgrade के समय बस restart करना पड़ता है, और जब performance महत्वपूर्ण हो तो यह क़ीमती साबित होता है
    • Go आने से पहले 2000 के दशक में CGI प्रोग्राम C/C++ में बनाना safety और development difficulty दोनों के लिहाज़ से कठिन था

      • Perl और Python में interpreter startup और compile cost काफ़ी ज़्यादा थी, और Java व्यवहार में उससे भी धीमा था
      • AWS Lambda = CGI model का पुनर्जन्म, इस बात से सहमति
      • अब ऐसा लगता है कि हम लगभग managed FastCGI जैसे model पर वापस आ गए हैं
      • केवल executable upload करके चल जाना चाहिए, लेकिन उसके ऊपर बेवजह जटिलता जोड़ने वाली technologies की बाढ़ पर अफ़सोस जताया गया
  • आज के 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 की भूलभुलैया में फँसना आसान है

      • यह देखकर हैरानी हुई कि core technology के ऊपर abstraction layers चढ़ाकर Director/VP पदों तक पहुँचने के इतने उदाहरण हैं
  • CGI का एक फ़ायदा यह है कि multi-tenant environment में isolation primitives अलग से बनाने की ज़रूरत नहीं पड़ती

    • एक request में bug हो तो भी process isolation की वजह से दूसरी requests प्रभावित नहीं होतीं
    • infinite loop भी preemptive scheduling की वजह से सीधे DoS में नहीं बदलता
    • rlimit से लंबे समय तक चलने वाली requests को ज़बरदस्ती terminate किया जा सकता है
    • cgroup का उपयोग करके tenant के हिसाब से memory, CPU, disk/network IO का निष्पक्ष allocation किया जा सकता है
    • namespaces/jails और privilege separation से हर request की access permissions सीमित की जा सकती हैं
  • CGI scripts की वजह से perl को fast startup time के लिए optimize किया गया था

    • time perl -e '' चलाने पर perl 5ms, python3 33ms, और ruby 77ms लेता है, जिससे perl का तेज़ startup time दिखता है

      • tcc mob branch की #!/bin/tcc -run शैली की scripts, perl से 1.3 गुना तेज़ बताई गईं
      • Julia, Java VM, thread PHP आदि के startup time बहुत लंबे होने के उदाहरण भी दिए गए
      • लोग आदतन "बड़े environment" पर निर्भर होने लगते हैं
      • Lisp community में image उपयोग करने से यही बात दोहराई जाती रही, और "emacs is bloated" meme भी वहीं से निकला
      • 90 के दशक के मध्य और उत्तरार्ध में Perl का स्वर्णकाल सच में CGI की वजह से संभव हुआ था
      • उस समय getline भी standard नहीं था, इसलिए third-party C libraries सैकड़ों से हज़ारों lines में लिखी जाती थीं, यह याद किया गया
      • आख़िरकार technologies का चुनाव अक्सर "reputation" पर होता है, और ज़्यादातर सीखना दोस्तों की recommendation से शुरू होता है
  • 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 बनाया गया

    • desktop browser में सबसे अच्छा अनुभव मिलता है
    • HN traffic data के आधार पर वेब पर वास्तविक request flow देखा जा सकता है
  • आजकल complex architectures की ओर बढ़ना संदिग्ध लगने लगा; शायद अच्छे hardware के साथ पुरानी technologies भी काफ़ी हो सकती हैं

    • लाखों लोगों को real-time stock quotes देने वाली system design के सवाल पर पहले Kafka, pubsub जैसी complex stream structures दिमाग़ में आईं, लेकिन अंत में server पर static files रखने जैसी simple approach पर भी विचार हुआ

    • इस तरीके की वास्तविक operating cost कैसी होगी, यह जानने की उत्सुकता है

      • व्यवहार में लगभग सभी web APIs की latency DB query या ML model query तय करती है
      • बाकी process में Python जैसी धीमी भाषा भी इस्तेमाल हो तो उसका असर बहुत बड़ा नहीं होता
      • अगर केवल कम बदलने वाला data return करना हो, तो NIC की limit तक पहुँचना भी आसान हो सकता है
  • यह serverless architecture जैसा है, लेकिन उससे कहीं ज़्यादा simple और सस्ता

    • उत्सुकता जताई गई कि क्या business दुनिया में इसका वास्तव में उपयोग होता है
  • इस तरह की पारंपरिक संरचना पर फिर से विचार करने के बजाय सिर्फ़ "serverless functions" नाम का नया paradigm बना देने पर अफ़सोस जताया गया

    • Lambda जैसी serverless functions में अलग सुरक्षा तंत्र (micro VM आदि) ज़रूर हैं, लेकिन फिर भी ऐसा लगता है कि CGI और permission tuning भर से कहीं कम complexity में बहुत दूर तक जाया जा सकता था
 
regentag 2025-07-07

cgi तो फिर भी समझ आता है, लेकिन jsp पर लोगों की प्रतिक्रिया काफ़ी चौंकाने वाली है lol
क्या jsp सच में अब उस हद तक का प्राचीन अवशेष बन चुका है?