ओपनरेस्टी में तीन सामान्यतः उपयोग होने वाली Lua Resty लाइब्रेरीज़
API7.ai
January 13, 2023
प्रोग्रामिंग भाषाओं और प्लेटफॉर्म्स के बारे में सीखना अक्सर सिंटैक्स के बजाय मानक और तृतीय-पक्ष लाइब्रेरीज़ को समझने का मामला होता है। इसके API और प्रदर्शन अनुकूलन तकनीकों को सीखने के बाद, हमें विभिन्न lua-resty लाइब्रेरीज़ के उपयोग को सीखने की आवश्यकता होती है ताकि हमारे OpenResty की क्षमताओं को और अधिक परिदृश्यों में विस्तारित किया जा सके।
lua-resty लाइब्रेरी कहाँ मिलेगी?
PHP, Python, और JavaScript की तुलना में, वर्तमान OpenResty मानक और तृतीय-पक्ष लाइब्रेरीज़ अभी भी अपेक्षाकृत कम हैं, और सही lua-resty लाइब्रेरीज़ ढूंढना आसान नहीं है। हालांकि, यहाँ दो स्रोत हैं जो आपको उन्हें तेजी से ढूंढने में मदद कर सकते हैं।
पहला सुझाव है Aapo द्वारा बनाए रखा गया awesome-resty रिपॉजिटरी। यह रिपॉजिटरी OpenResty से संबंधित लाइब्रेरीज़ को श्रेणी के अनुसार व्यवस्थित करता है और सभी को शामिल करता है, जिसमें NGINX C मॉड्यूल, lua-resty लाइब्रेरीज़, वेब फ्रेमवर्क, रूटिंग लाइब्रेरीज़, टेम्प्लेट्स, टेस्टिंग फ्रेमवर्क आदि शामिल हैं। यह OpenResty संसाधनों के लिए आपकी पहली पसंद है।
यदि आपको Aapo की रिपॉजिटरी में सही लाइब्रेरी नहीं मिलती है, तो आप luarocks, topm, या GitHub पर भी देख सकते हैं। हो सकता है कि कुछ लाइब्रेरीज़ हों जो लंबे समय से खुला स्रोत नहीं हैं और जिन पर ज्यादा ध्यान नहीं दिया गया है।
पिछले लेखों में, हमने कई उपयोगी लाइब्रेरीज़ जैसे lua-resty-mlcache, lua-resty-traffic, lua-resty-shell आदि के बारे में सीखा है। आज, OpenResty प्रदर्शन अनुकूलन खंड के अंतिम लेख में, हम 3 और अनोखी परिधीय लाइब्रेरीज़ के बारे में जानेंगे, जो सभी समुदाय के डेवलपर्स द्वारा योगदान की गई हैं।
ngx.var का प्रदर्शन सुधार
पहले, एक C मॉड्यूल देखते हैं: lua-var-nginx-module। जैसा कि मैंने पहले बताया, ngx.var एक अपेक्षाकृत प्रदर्शन-खपत करने वाला ऑपरेशन है। इसलिए, व्यवहार में, हमें ngx.ctx को कैश के रूप में उपयोग करने की आवश्यकता होती है।
तो क्या ngx.var के प्रदर्शन समस्या को पूरी तरह से हल करने का कोई तरीका है?
यह C मॉड्यूल इस क्षेत्र में कुछ प्रयोग करता है, और परिणाम उल्लेखनीय हैं, जो ngx.var की तुलना में 5 गुना प्रदर्शन सुधार दिखाता है। यह FFI दृष्टिकोण का उपयोग करता है, इसलिए आपको पहले निम्नलिखित कंपाइल विकल्प के साथ OpenResty को कंपाइल करना होगा।
./configure --prefix=/opt/openresty \ --add-module=/path/to/lua-var-nginx-module
फिर luarocks का उपयोग करके lua लाइब्रेरी को निम्नलिखित तरीके से इंस्टॉल करें:
luarocks install lua-resty-ngxvar
यहाँ कॉल की जाने वाली विधि भी बहुत सरल है, केवल एक लाइन की fetch फ़ंक्शन की आवश्यकता होती है। यह मूल ngx.var.remote_addr के बराबर काम करता है जो क्लाइंट का IP पता प्राप्त करता है।
content_by_lua_block { local var = require("resty.ngxvar") ngx.say(var.fetch("remote_addr")) }
इन बुनियादी ऑपरेशन्स को समझने के बाद, आप इस मॉड्यूल के बारे में और अधिक जिज्ञासु हो सकते हैं कि यह कैसे महत्वपूर्ण प्रदर्शन सुधार प्राप्त करता है। जैसा कि हम हमेशा कहते हैं, "स्रोत कोड के सामने कोई रहस्य नहीं होता"। तो आइए जानें कि remote_addr वेरिएबल को कैसे प्राप्त किया जाता है।
ngx_int_t ngx_http_lua_var_ffi_remote_addr(ngx_http_request_t *r, ngx_str_t *remote_addr) { remote_addr->len = r->connection->addr_text.len; remote_addr->data = r->connection->addr_text.data; return NGX_OK; }
इस कोड को पढ़ने के बाद, आप देखेंगे कि यह Lua FFI दृष्टिकोण lua-resty-core दृष्टिकोण के समान है। इसमें FFI का उपयोग करके सीधे वेरिएबल्स प्राप्त करने का स्पष्ट लाभ है, जो ngx.var की मूल खोज लॉजिक को बायपास करता है। इसका नुकसान स्पष्ट है: प्रत्येक वेरिएबल के लिए C फ़ंक्शन और FFI कॉल जोड़ना, जो समय और ऊर्जा खपत करने वाला है।
कुछ लोग पूछ सकते हैं, "मैं यह क्यों कहूंगा कि यह समय और ऊर्जा खपत करने वाला है? क्या उपरोक्त C कोड काफी मजबूत नहीं लगता?" आइए इन कोड लाइनों के स्रोत को देखें, जो NGINX कोड में src/http/ngx_http_variables.c से आते हैं।
static ngx_int_t ngx_http_variable_remote_addr(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { v->len = r->connection->addr_text.len; v->valid = 1; v->no_cacheable = 0; v->not_found = 0; v->data = r->connection->addr_text.data; return NGX_OK; }
स्रोत कोड देखने के बाद, रहस्य खुल गया! lua-var-nginx-module NGINX वेरिएबल कोड का एक पोर्टर है, जिसमें बाहरी परत में FFI रैपिंग है, और इस तरह से यह प्रदर्शन अनुकूलन प्राप्त करता है। यह एक अच्छा विचार है और अनुकूलन के लिए एक अच्छी दिशा है।
जब हम किसी लाइब्रेरी या टूल को सीखते हैं, तो हमें केवल ऑपरेशन के स्तर पर नहीं रुकना चाहिए, बल्कि यह भी पूछना चाहिए कि हम इसे क्यों करते हैं और स्रोत कोड को देखना चाहिए। बेशक, मैं आपको अधिक NGINX वेरिएबल्स का समर्थन करने के लिए कोड योगदान करने के लिए भी प्रोत्साहित करता हूँ।
JSON Schema
यहाँ मैं एक lua-resty लाइब्रेरी का परिचय देता हूँ: lua-rapidjson। यह rapidjson, Tencent के खुले स्रोत JSON लाइब्रेरी का एक रैपर है, और इसकी प्रदर्शन के लिए जाना जाता है। यहाँ, हम इसके और cjson के बीच के अंतर पर ध्यान केंद्रित करते हैं: JSON Schema समर्थन।
JSON Schema एक सामान्य मानक है जो हमें एक इंटरफ़ेस में पैरामीटर्स के प्रारूप और उन्हें कैसे मान्य किया जाना है, का सटीक वर्णन करने की अनुमति देता है। यहाँ एक सरल उदाहरण है:
"stringArray": { "type": "array", "items": { "type": "string" }, "minItems": 1, "uniqueItems": true }
यह JSON सटीक रूप से वर्णन करता है कि stringArray पैरामीटर एक स्ट्रिंग सरणी है और सरणी खाली नहीं हो सकती है, न ही सरणी तत्व डुप्लिकेट हो सकते हैं।
lua-rapidjson हमें OpenResty में JSON Schema का उपयोग करने की अनुमति देता है, जो इंटरफ़ेस मान्यता के लिए बहुत सुविधा प्रदान कर सकता है। उदाहरण के लिए, पहले वर्णित लिमिट काउंट इंटरफ़ेस के लिए, हम निम्नलिखित schema का उपयोग कर सकते हैं:
local schema = { type = "object", properties = { count = {type = "integer", minimum = 0}, time_window = {type = "integer", minimum = 0}, key = {type = "string", enum = {"remote_addr", "server_addr"}}, rejected_code = {type = "integer", minimum = 200, maximum = 600}, }, additionalProperties = false, required = {"count", "time_window", "key", "rejected_code"}, }
आप पाएंगे कि इससे दो बहुत स्पष्ट लाभ हो सकते हैं:
- फ्रंट एंड के लिए, फ्रंट एंड सीधे इस schema विवरण का उपयोग कर सकता है फ्रंट एंड पेज डेवलपमेंट और पैरामीटर मान्यता के लिए, बिना बैक एंड की चिंता किए।
- बैक एंड के लिए, बैक एंड सीधे
lua-rapidjsonके schema मान्यता फ़ंक्शनSchemaValidatorका उपयोग करके इंटरफ़ेस की वैधता का निर्धारण कर सकता है, और अतिरिक्त कोड लिखने की आवश्यकता नहीं है।
Worker संचार
अंत में, मैं OpenResty में workers के बीच संचार सक्षम करने वाली lua-resty लाइब्रेरी के बारे में बात करना चाहूंगा, जहाँ workers के बीच सीधे संचार का कोई तंत्र नहीं है, जो कई समस्याएं पैदा करता है। आइए एक परिदृश्य की कल्पना करें:
एक OpenResty सेवा में 24 worker प्रक्रियाएं हैं, और जब प्रशासक REST HTTP APIs के माध्यम से सिस्टम का एक कॉन्फ़िगरेशन अपडेट करता है, तो केवल एक
Workerप्रशासक से अपडेट प्राप्त करता है और डेटाबेस में परिणाम लिखता है, अपने स्वयं के Worker के भीतरshared dictऔरlru cacheको अपडेट करता है। तो, अन्य 23 workers को यह कॉन्फ़िगरेशन अपडेट करने के लिए कैसे सूचित किया जा सकता है?
कई Workers के बीच एक सूचना तंत्र की आवश्यकता है जो उपरोक्त कार्य को पूरा कर सके। OpenResty द्वारा समर्थित नहीं होने के मामले में, हमें shared dict डेटा का उपयोग करके workers के बीच डेटा साझा करना होगा।
lua-resty-worker-events इस विचार का एक ठोस कार्यान्वयन है। यह एक shared dict में एक संस्करण संख्या बनाए रखता है, और जब एक नया संदेश प्रकाशित किया जाता है, तो यह संस्करण संख्या में एक जोड़ता है और संदेश की सामग्री को संस्करण संख्या के साथ key के रूप में डिक्शनरी में डालता है।
event_id, err = _dict:incr(KEY_LAST_ID, 1) success, err = _dict:add(KEY_DATA .. tostring(event_id), json)
इसके अलावा, ngx.timer का उपयोग करके पृष्ठभूमि में एक polling लूप बनाया जाता है जो डिफ़ॉल्ट रूप से 1 सेकंड के अंतराल पर संस्करण संख्या में परिवर्तन की जाँच करता है:
local event_id, err = get_event_id() if event_id == _last_event then return "done" end
इस तरह, जैसे ही एक नया इवेंट नोटिफिकेशन प्रोसेस करने के लिए पाया जाता है, संदेश की सामग्री को संस्करण संख्या के आधार पर shared dict से प्राप्त किया जाता है:
while _last_event < event_id do count = count + 1 _last_event = _last_event + 1 data, err = _dict:get(KEY_DATA..tostring(_last_event)) end
कुल मिलाकर, हालांकि lua-resty-worker-events में एक सेकंड की देरी होती है, फिर भी यह Worker-to-Worker इवेंट नोटिफिकेशन तंत्र को लागू करता है।
हालांकि, कुछ रियल-टाइम परिदृश्यों में, जैसे संदेश पुशिंग, OpenResty की Worker प्रक्रियाओं के बीच सीधे संचार की कमी आपको कुछ समस्याएं पैदा कर सकती है। इसके लिए कोई बेहतर समाधान नहीं है, लेकिन यदि आपके पास अच्छे विचार हैं, तो कृपया उन्हें Github पर चर्चा करने के लिए स्वतंत्र महसूस करें। OpenResty की कई सुविधाएं समुदाय द्वारा संचालित होती हैं ताकि एक सकारात्मक पारिस्थितिक चक्र बनाया जा सके।
सारांश
आज हमने जिन तीन लाइब्रेरीज़ का परिचय दिया है, वे अनोखी हैं और OpenResty एप्लिकेशन्स के लिए और अधिक संभावनाएं लाती हैं। अंत में, एक इंटरैक्टिव विषय, क्या आपने OpenResty के आसपास कोई दिलचस्प लाइब्रेरीज़ पाई हैं? या आज वर्णित लाइब्रेरीज़ के बारे में आपको क्या पता चला या आश्चर्य हुआ? आप इस लेख को अपने आसपास के OpenResty उपयोगकर्ताओं को भेजकर एक साथ आदान-प्रदान और प्रगति करने के लिए स्वागत कर सकते हैं।