ओपनरेस्टी की किलर फीचर: डायनामिक
API7.ai
January 12, 2023
अब तक, हम OpenResty प्रदर्शन से संबंधित सामग्री के साथ लगभग पूरा कर चुके हैं। इन अनुकूलन तकनीकों को महारत हासिल करना और लचीले ढंग से लागू करना हमारे कोड के प्रदर्शन को काफी हद तक सुधार सकता है। आज, प्रदर्शन अनुकूलन के अंतिम भाग में, आइए OpenResty में एक आमतौर पर कम आंकी जाने वाली क्षमता के बारे में सीखें: "डायनामिक"।
आइए शुरू करते हैं कि डायनामिक क्या है और यह प्रदर्शन से कैसे संबंधित है। इस संदर्भ में डायनामिक का मतलब है कि प्रोग्राम रनटाइम पर पैरामीटर, कॉन्फ़िगरेशन और यहां तक कि अपने कोड को बदल सकते हैं, बिना रीलोड किए। विशेष रूप से, NGINX और OpenResty में, आप अपस्ट्रीम, SSL सर्टिफिकेट्स, और रेट-लिमिट थ्रेशोल्ड को बिना सेवा को रीस्टार्ट किए बदल सकते हैं, जिससे डायनामिक प्राप्त होता है। जहां तक डायनामिक और प्रदर्शन के बीच संबंध का सवाल है, यह स्पष्ट है कि अगर इस प्रकार के ऑपरेशन डायनामिक रूप से नहीं किए जा सकते हैं, तो NGINX सेवाओं के लगातार रीलोड होने से स्वाभाविक रूप से प्रदर्शन में कमी आएगी।
हालांकि, हम जानते हैं कि NGINX का ओपन-सोर्स संस्करण डायनामिक सुविधाओं का समर्थन नहीं करता है, इसलिए आपको अपस्ट्रीम SSL सर्टिफिकेट्स को बदलने के लिए कॉन्फ़िगरेशन फ़ाइल को संशोधित करना होगा और सेवा को रीस्टार्ट करना होगा ताकि वे प्रभावी हो सकें। NGINX Plus (NGINX का वाणिज्यिक संस्करण) कुछ डायनामिक क्षमताएं प्रदान करता है, और आप REST API का उपयोग करके अपडेट कर सकते हैं, लेकिन यह सबसे अच्छा एक कम-से-कम मूलभूत सुधार है।
OpenResty में, ये बंधन मौजूद नहीं हैं, और डायनामिक OpenResty की किलर सुविधा है। आप सोच रहे होंगे कि NGINX पर आधारित OpenResty डायनामिक का समर्थन कैसे कर सकता है। कारण सरल है: NGINX लॉजिक C मॉड्यूल के माध्यम से किया जाता है, जबकि OpenResty Lua, एक स्क्रिप्टिंग भाषा के माध्यम से किया जाता है। स्क्रिप्टिंग भाषाओं के लाभों में से एक यह है कि वे रनटाइम पर डायनामिक रूप से बदल सकते हैं।
कोड को डायनामिक रूप से लोड करना
यहां बताया गया है कि OpenResty में Lua कोड को डायनामिक रूप से कैसे लोड किया जाए।
resty -e 'local s = [[ngx.say("hello world")]] local func, err = loadstring(s) func()'
हम देख सकते हैं कि केवल कुछ लाइनों के कोड में, हम एक स्ट्रिंग को Lua फ़ंक्शन में बदल सकते हैं और इसे चला सकते हैं। आइए इन लाइनों के कोड को और करीब से देखें:
- पहले, हम एक स्ट्रिंग घोषित करते हैं जिसकी सामग्री Lua कोड का एक टुकड़ा है जो
hello worldप्रिंट करता है; - फिर, Lua में
loadstringफ़ंक्शन का उपयोग करके, स्ट्रिंग ऑब्जेक्ट को फ़ंक्शन ऑब्जेक्टfuncमें बदल दिया जाता है। - अंत में, फ़ंक्शन नाम के साथ कोष्ठक जोड़कर
funcको निष्पादित किया जाता है औरhello worldप्रिंट किया जाता है।
बेशक, हम इस कोड के आधार पर और अधिक दिलचस्प और व्यावहारिक फ़ंक्शन्स को भी विस्तारित कर सकते हैं। आगे, मैं आपको इसे आज़माने के लिए ले जाऊंगा।
फ़ंक्शन 1: FaaS
पहला है FaaS (Function-as-a-Service), जो हाल ही में एक बहुत लोकप्रिय तकनीकी दिशा रही है। आइए देखें कि इसे OpenResty में कैसे लागू किया जाए। पहले बताए गए कोड में, स्ट्रिंग एक Lua कोड है। हम इसे एक Lua फ़ंक्शन में भी बदल सकते हैं:
local s = [[ return function() ngx.say("hello world") end ]]
जैसा कि हमने कहा, Lua में फ़ंक्शन प्रथम श्रेणी के नागरिक हैं, और यह कोड एक अनाम फ़ंक्शन लौटाता है। जब हम इस अनाम फ़ंक्शन को निष्पादित करते हैं, तो हम pcall का उपयोग करके एक सुरक्षा परत प्रदान करते हैं। pcall फ़ंक्शन को सुरक्षित मोड में चलाएगा और अपवाद को पकड़ेगा। यदि यह सामान्य है, तो यह true और निष्पादन परिणाम लौटाएगा। यदि यह विफल होता है, तो यह false और त्रुटि जानकारी लौटाएगा, जो निम्नलिखित कोड है:
local func1, err = loadstring(s) local ret, func = pcall(func1)
स्वाभाविक रूप से, यदि आप उपरोक्त दोनों भागों को जोड़ते हैं, तो आपको एक पूर्ण और संचालन योग्य उदाहरण मिलेगा:
resty -e 'local s = [[ return function() ngx.say("hello world") end ]] local func1 = loadstring(s) local ret, func = pcall(func1) func()'
एक कदम आगे बढ़ते हुए, हम फ़ंक्शन्स वाली स्ट्रिंग s को उस रूप में बदल सकते हैं जिसे उपयोगकर्ता निर्दिष्ट कर सकता है और इसके निष्पादन के लिए शर्तें जोड़ सकता है। यह FaaS का प्रोटोटाइप है। यहां, मैं एक पूर्ण कार्यान्वयन प्रदान करता हूं। यदि FaaS में रुचि है और आप अपना शोध जारी रखना चाहते हैं, तो लिंक के माध्यम से अधिक जानें।
फ़ंक्शन 2: एज कंप्यूटिंग
OpenResty की डायनामिक का उपयोग FaaS के लिए किया जा सकता है, जिससे स्क्रिप्टिंग भाषा की डायनामिक को फ़ंक्शन स्तर तक परिष्कृत किया जा सकता है, और एज कंप्यूटिंग में डायनामिक भूमिका निभाई जा सकती है।
इन लाभों के कारण, हम OpenResty के टेंटेकल्स को API गेटवे, WAF (वेब एप्लिकेशन फ़ायरवॉल), वेब सर्वर, और अन्य सर्वर सिरों से उपयोगकर्ताओं के सबसे निकट एज नोड्स तक विस्तारित कर सकते हैं, जैसे IoT डिवाइस, CDN एज नोड्स, राउटर आदि।
यह केवल एक कल्पना नहीं है। OpenResty उपरोक्त क्षेत्रों में व्यापक रूप से उपयोग किया गया है। CDN एज नोड्स के उदाहरण के रूप में, OpenResty का सबसे बड़ा उपयोगकर्ता Cloudflare, OpenResty की डायनामिक विशेषताओं की मदद से लंबे समय से CDN एज नोड्स का डायनामिक नियंत्रण प्राप्त कर चुका है।
Cloudflare का दृष्टिकोण डायनामिक रूप से कोड लोड करने के उपरोक्त सिद्धांत के समान है, जिसे मोटे तौर पर निम्नलिखित चरणों में विभाजित किया जा सकता है:
- पहले, की-वैल्यू डेटाबेस क्लस्टर से बदले गए कोड फ़ाइलों को प्राप्त करें। विधि बैकग्राउंड टाइमर पोलिंग या "प्रकाशन-सदस्यता" मोड हो सकती है;
- फिर, स्थानीय डिस्क पर पुरानी फ़ाइल को अपडेटेड कोड फ़ाइल से बदलें और
loadstringऔरpcallविधियों का उपयोग करके मेमोरी में लोड किए गए कैश को अपडेट करें;
इस तरह, अगले क्लाइंट अनुरोध को संसाधित करने के लिए अपडेटेड कोड लॉजिक के माध्यम से जाएगा। बेशक, व्यावहारिक अनुप्रयोग में उपरोक्त चरणों से अधिक विवरणों पर विचार करना चाहिए, जैसे संस्करण नियंत्रण और रोलबैक, अपवाद हैंडलिंग, नेटवर्क व्यवधान, एज नोड रीस्टार्ट आदि, लेकिन समग्र प्रक्रिया अपरिवर्तित रहती है।
यदि हम Cloudflare के दृष्टिकोण को CDN एज नोड्स से अन्य एज परिदृश्यों में ले जाते हैं, तो हम एज नोड डिवाइस को बहुत सारी कंप्यूटिंग शक्ति डायनामिक रूप से आवंटित कर सकते हैं। यह न केवल एज नोड्स की कंप्यूटिंग शक्ति का पूरा उपयोग कर सकता है, बल्कि उपयोगकर्ताओं को अनुरोधों के लिए तेज प्रतिक्रिया प्राप्त करने में सक्षम बना सकता है क्योंकि एज नोड मूल डेटा को संसाधित करेगा और फिर इसे रिमोट सर्वर को सारांशित करेगा, जिससे डेटा ट्रांसमिशन की मात्रा काफी कम हो जाती है।
हालांकि, FaaS और एज कंप्यूटिंग में उत्कृष्ट काम करने के लिए, OpenResty की डायनामिक केवल एक अच्छा आधार है। आपको अपने आसपास के पारिस्थितिकी तंत्र के सुधार और निर्माताओं की भागीदारी पर भी विचार करने की आवश्यकता है, जो केवल एक तकनीकी श्रेणी नहीं है।
डायनामिक अपस्ट्रीम
अब, आइए अपने विचारों को OpenResty पर वापस लाएं कि डायनामिक अपस्ट्रीम कैसे प्राप्त किया जाए। lua-resty-core ngx.balancer का एक लाइब्रेरी प्रदान करता है जो अपस्ट्रीम को सेट करने के लिए है। इसे OpenResty के balancer चरण में रखा जाना चाहिए:
balancer_by_lua_block { local balancer = require "ngx.balancer" local host = "127.0.0.2" local port = 8080 local ok, err = balancer.set_current_peer(host, port) if not ok then ngx.log(ngx.ERR, "failed to set the current peer: ", err) return ngx.exit(500) end }
set_current_peer फ़ंक्शन अपस्ट्रीम IP पता और पोर्ट सेट करता है। हालांकि, हम यह बताना चाहते हैं कि यहां डोमेन नाम समर्थित नहीं है। हमें डोमेन नाम और IP के लिए lua-resty-dns लाइब्रेरी का उपयोग करके एक परत विश्लेषण करने की आवश्यकता है।
हालांकि, ngx.balancer अपेक्षाकृत निम्न स्तर का है। हालांकि इसका उपयोग अपस्ट्रीम सेट करने के लिए किया जा सकता है, डायनामिक अपस्ट्रीम प्राप्त करना बहुत सरल नहीं है। इसलिए, ngx.balancer के सामने दो फ़ंक्शन्स की आवश्यकता है:
- पहला, यह तय करें कि अपस्ट्रीम चयन एल्गोरिदम
consistent hashहै याroundrobin; - दूसरा, अपस्ट्रीम स्वास्थ्य जांच तंत्र, जिसे अस्वस्थ अपस्ट्रीम को हटाने और जब अस्वस्थ अपस्ट्रीम स्वस्थ हो जाए तो इसे फिर से जोड़ने की आवश्यकता है।
OpenResty के आधिकारिक lua-resty-balancer लाइब्रेरी में दो प्रकार के एल्गोरिदम शामिल हैं: resty.chash और resty.roundrobin पहले फ़ंक्शन को पूरा करने के लिए, और इसमें lua-resty-upstream-healthcheck दूसरे फ़ंक्शन को पूरा करने का प्रयास करता है।
हालांकि, अभी भी दो समस्याएं हैं।
पहला बिंदु अंतिम मील के पूर्ण कार्यान्वयन की कमी है। ngx.balancer, lua-resty-balancer, और lua-resty-upstream-healthcheck को डायनामिक अपस्ट्रीम के कार्यों को संयोजित करने के लिए बदलें, लेकिन अभी भी कुछ काम की आवश्यकता है, जो अधिकांश डेवलपर्स को रोकता है।
दूसरा, lua-resty-upstream-healthcheck का कार्यान्वयन पूर्ण नहीं है। इसमें केवल पैसिव स्वास्थ्य जांच है लेकिन एक्टिव स्वास्थ्य जांच नहीं है।
यहां क्लाइंट्स के अनुरोध पैसिव स्वास्थ्य जांच को ट्रिगर करते हैं और फिर अपस्ट्रीम रिटर्न वैल्यू को स्वास्थ्य की स्थिति निर्धारित करने के लिए एक शर्त के रूप में विश्लेषण करते हैं। यदि कोई क्लाइंट अनुरोध नहीं है, तो अपस्ट्रीम स्वस्थ है या नहीं यह अज्ञात है। एक्टिव स्वास्थ्य जांच इस दोष को दूर कर सकती है। यह ngx.timer का उपयोग करके निर्दिष्ट अपस्ट्रीम इंटरफ़ेस को नियमित रूप से पोल करके स्वास्थ्य स्थिति का पता लगाती है।
इसलिए, वास्तविक अभ्यास में, हम आमतौर पर lua-resty-healthcheck का उपयोग करने की सलाह देते हैं ताकि अपस्ट्रीम स्वास्थ्य जांच पूरी की जा सके। इसका लाभ यह है कि इसमें एक्टिव और पैसिव स्वास्थ्य जांच शामिल है, और इसे कई परियोजनाओं में सत्यापित किया गया है जिससे इसकी विश्वसनीयता अधिक है।
इसके अलावा, उभरते माइक्रोसर्विस API गेटवे Apache APISIX ने lua-resty-upstream-healthcheck के आधार पर डायनामिक अपस्ट्रीम का एक पूर्ण कार्यान्वयन किया है। हम इसके कार्यान्वयन का संदर्भ ले सकते हैं। इसमें कुल 400 लाइनें कोड हैं। आप इसे आसानी से अपने प्रोजेक्ट में उपयोग के लिए निकाल सकते हैं।
सारांश
OpenResty की डायनामिक के संबंध में, आप इसे किन क्षेत्रों और परिदृश्यों में लाभ उठा सकते हैं? आप इस अध्याय में प्रस्तुत प्रत्येक भाग की सामग्री को और अधिक विस्तृत और गहन विश्लेषण के लिए विस्तारित भी कर सकते हैं।
आप इस लेख को साझा करने और अधिक लोगों के साथ सीखने और प्रगति करने के लिए स्वागत करते हैं।