इस फ़ंक्शन पर विचार करें, जो एक URL पर GET अनुरोध भेजता है और HTTP स्टेटस कोड लौटाता है। HTTP/1 (GODEBUG=http2client=0) का उपयोग करते हुए, लेखक की मशीन पर Go 1.26 में index.golang.org के विरुद्ग इसे 100 बार कॉल करने में लगभग 710 मिलीसेकंड लगते हैं। Go 1.27 पर वही प्रोग्राम लगभग 150 मिलीसेकंड में चलता है, जो लगभग 5 गुना तेज़ है।
यह अंतर नए कनेक्शन स्थापित करने की लागत से आता है। नए कनेक्शन पर अनुरोध के लिए एक TCP हैंडशेक (1 राउंड-ट्रिप टाइम, या RTT), एक TLS हैंडशेक (TLS 1.2 के तहत 2 RTT) और फिर HTTP अनुरोध स्वयं चाहिए, यानी कुल लगभग 3 RTT। क्षेत्रों के बीच संचार में एकतरफ़ा विलंबता अक्सर 50 ms या उससे अधिक होती है, इसलिए केवल सेटअप में ही लगभग 300 ms लग सकते हैं। index.golang.org के मामले में भी, जो TLS 1.3 का उपयोग करता है और अपेक्षाकृत कम विलंबता देता है, नया कनेक्शन खोलना अब भी काफ़ी महसूस होता है।
इस लागत से बचने के लिए HTTP क्लाइंट और सर्वर कनेक्शन का पुन: उपयोग करने का प्रयास करते हैं। HTTP/1.0 क्लाइंट और सर्वर Connection: keep-alive हेडर के साथ इसे चुनते हैं, जबकि HTTP/1.1 कनेक्शन डिफ़ॉल्ट रूप से स्थायी होते हैं। HTTP/2 एक ही TCP कनेक्शन पर कई अनुरोधों और प्रतिक्रियाओं को मल्टीप्लेक्स करता है।
फिर भी, HTTP/1 में पुन: उपयोग विफल हो सकता है। एक ही कनेक्शन पर प्रतिक्रियाएँ क्रम से भेजी जाती हैं, इसलिए net/http अगली प्रतिक्रिया की शुरुआत तभी ढूँढ सकता है जब वर्तमान प्रतिक्रिया का बॉडी अंत तक पढ़ लिया गया हो। उदाहरण में, प्रतिक्रिया बॉडी कभी नहीं पढ़ी जाती, इसलिए जब resp.Body.Close कॉल होता है, तो net/http को बिना पढ़ी बॉडी मिलती है और वह कनेक्शन को सुरक्षित रूप से पुन: उपयोग नहीं कर सकता। Go 1.26 तक, इसका अर्थ है हर अनुरोध के लिए नया कनेक्शन।
स्रोत: Hacker News · HeadlinesBriefing द्वारा सारांशित