---
title: "वेब सर्वर से परे: प्रिविलेज्ड प्रोसेस और टाइमर टास्क्स - API7.ai"
description: "Privileged Process और Timer Tasks महत्वपूर्ण विशेषताएं हैं जो OpenResty को NGINX और अन्य वेब सर्वर से अलग करती हैं।"
url: "https://api7.ai/hi/learning-center/openresty/privileged-process-and-timer-tasks"
---

# वेब सर्वर से परे: प्रिविलेज्ड प्रोसेस और टाइमर टास्क्स

API7.ai

November 3, 2022

[OpenResty (NGINX + Lua)](https://api7.ai/learning-center/openresty)

पिछले लेख में, हमने OpenResty APIs, `shared dict`, और `cosocket` का परिचय दिया, जो सभी NGINX और वेब सर्वर के क्षेत्र में कार्यक्षमता को लागू करते हैं, जिससे एक प्रोग्रामेबल वेब सर्वर प्रदान किया जाता है जो कम लागत और आसान रखरखाव वाला होता है।

हालांकि, OpenResty इससे भी अधिक कर सकता है। आज हम OpenResty में कुछ ऐसी सुविधाओं को चुनेंगे जो वेब सर्वर से परे हैं और उनका परिचय देंगे। ये हैं टाइमर टास्क्स, प्रिविलेज्ड प्रोसेस, और नॉन-ब्लॉकिंग `ngx.pipe`।

## टाइमर टास्क्स

OpenResty में, हमें कभी-कभी पृष्ठभूमि में नियमित रूप से विशिष्ट कार्य करने की आवश्यकता होती है, जैसे डेटा सिंक्रनाइज़ करना, लॉग्स साफ़ करना आदि। यदि आप इसे डिज़ाइन करते हैं, तो आप इसे कैसे करेंगे? सबसे आसान तरीका यह है कि इन कार्यों को करने के लिए एक API इंटरफ़ेस प्रदान किया जाए, फिर सिस्टम के `crontab` का उपयोग करके नियमित अंतराल पर `curl` को इस इंटरफ़ेस तक पहुंचने के लिए कॉल किया जाए, और फिर इस आवश्यकता को अप्रत्यक्ष रूप से पूरा किया जाए।

हालांकि, यह न केवल खंडित होगा बल्कि ऑपरेशन और रखरखाव में उच्च जटिलता भी लाएगा। इसलिए, OpenResty ने इस तरह की आवश्यकता को पूरा करने के लिए `ngx.timer` प्रदान किया है। आप `ngx.timer` को OpenResty द्वारा सिम्युलेट किए गए क्लाइंट अनुरोध के रूप में ले सकते हैं जो संबंधित कॉलबैक फ़ंक्शन को ट्रिगर करता है।

OpenResty के टाइमर टास्क्स को निम्नलिखित दो प्रकारों में विभाजित किया जा सकता है।

- `ngx.timer.at` का उपयोग एक बार के टाइमर टास्क्स को निष्पादित करने के लिए किया जाता है।
- `ngx.timer.every` का उपयोग नियत अवधि के टाइमर टास्क्स को निष्पादित करने के लिए किया जाता है।

क्या आपको पिछले लेख के अंत में छोड़ा गया विचारोत्तेजक प्रश्न याद है? प्रश्न यह था कि `cosocket` को `init_worker_by_lua` में उपयोग नहीं किया जा सकता है, इस प्रतिबंध को कैसे तोड़ा जाए, और इसका उत्तर है `ngx.timer`।

निम्नलिखित कोड `0` की देरी के साथ एक टाइमर टास्क शुरू करता है। यह कॉलबैक `handler` फ़ंक्शन शुरू करता है, और इस फ़ंक्शन में, यह `cosocket` का उपयोग करके एक वेबसाइट तक पहुंचता है।

```
init_worker_by_lua_block {
    local function handler()
        local sock = ngx.socket.tcp()
        local ok, err = sock:connect(“api7.ai", 80)
    end

    local ok, err = ngx.timer.at(0, handler)
}
```

इस तरह, हम इस प्रतिबंध को दरकिनार कर देते हैं कि `cosocket` को इस स्तर पर उपयोग नहीं किया जा सकता है।

इस खंड की शुरुआत में हमने जिस उपयोगकर्ता आवश्यकता का उल्लेख किया था, `ngx.timer.at` उसे पूरा नहीं करता है; ऊपर दिए गए कोड उदाहरण में, यह एक बार का कार्य है।

तो, हम इसे नियमित रूप से कैसे करें? आपके पास `ngx.timer.at` API के आधार पर दो विकल्प प्रतीत होते हैं।

- आप कॉलबैक फ़ंक्शन में `while true` अनंत लूप का उपयोग करके स्वयं आवधिक कार्य को लागू कर सकते हैं जो कार्य को निष्पादित करने के बाद कुछ समय के लिए `sleep` करता है।
- आप कॉलबैक फ़ंक्शन के अंत में एक नया टाइमर भी बना सकते हैं।

हालांकि, चुनाव करने से पहले, हमें एक बात स्पष्ट करने की आवश्यकता है: टाइमर अनिवार्य रूप से एक अनुरोध है, हालांकि यह अनुरोध क्लाइंट द्वारा शुरू नहीं किया गया था। अनुरोध के लिए, इसे अपना कार्य पूरा करने के बाद बाहर निकलना होगा और इसे हमेशा के लिए रहने की अनुमति नहीं है। अन्यथा, यह विभिन्न प्रकार के संसाधन रिसाव का कारण बन सकता है।

इसलिए, `while true` का उपयोग करके आवधिक कार्य को लागू करने का पहला समाधान अविश्वसनीय है। दूसरा समाधान संभव है लेकिन यह पुनरावर्ती रूप से टाइमर बनाता है, जो समझने में आसान नहीं है।

तो, क्या कोई बेहतर समाधान है? OpenResty के पीछे नया `ngx.timer.every` API विशेष रूप से इस समस्या को हल करने के लिए डिज़ाइन किया गया है, और यह `crontab` के करीब एक समाधान है।

नकारात्मक पक्ष यह है कि एक बार टाइमर टास्क शुरू करने के बाद, आपके पास इसे रद्द करने का कोई मौका नहीं होता है। आखिरकार, `ngx.timer.cancel` अभी भी एक टू-डू फ़ंक्शन है।

इस बिंदु पर, आप एक समस्या का सामना करेंगे: टाइमर पृष्ठभूमि में चल रहा है और इसे रद्द नहीं किया जा सकता है; यदि कई टाइमर हैं, तो सिस्टम संसाधन समाप्त होने की संभावना है।

इसलिए, OpenResty ने उन्हें सीमित करने के लिए दो निर्देश, `lua_max_pending_timers` और `lua_max_running_timers` प्रदान किए हैं। पूर्व निष्पादित होने की प्रतीक्षा कर रहे टाइमर की अधिकतम संख्या का प्रतिनिधित्व करता है, और बाद वाला वर्तमान में चल रहे टाइमर की अधिकतम संख्या का प्रतिनिधित्व करता है।

आप वर्तमान में प्रतीक्षा कर रहे और चल रहे टाइमर टास्क्स के मान प्राप्त करने के लिए Lua API का भी उपयोग कर सकते हैं, जैसा कि निम्नलिखित दो उदाहरणों में दिखाया गया है।

```
content_by_lua_block {
    ngx.timer.at(3, function() end)
    ngx.say(ngx.timer.pending_count())
}
```

यह कोड `1` प्रिंट करेगा, जो इंगित करता है कि एक निर्धारित कार्य निष्पादित होने की प्रतीक्षा कर रहा है।

```
content_by_lua_block {
    ngx.timer.at(0.1, function() ngx.sleep(0.3) end)
    ngx.sleep(0.2)
    ngx.say(ngx.timer.running_count())
}
```

यह कोड `1` प्रिंट करेगा, जो इंगित करता है कि एक निर्धारित कार्य चल रहा है।

## प्रिविलेज्ड प्रोसेस

अगला, आइए प्रिविलेज्ड प्रोसेस को देखें। जैसा कि हम सभी जानते हैं, NGINX को `Master` प्रोसेस और `Worker` प्रोसेस में विभाजित किया गया है, जहां वर्कर प्रोसेस उपयोगकर्ता अनुरोधों को संभालते हैं। हम `lua-resty-core` में प्रदान किए गए `process.type` API के माध्यम से प्रोसेस के प्रकार को प्राप्त कर सकते हैं। उदाहरण के लिए, आप निम्नलिखित फ़ंक्शन को चलाने के लिए `resty` का उपयोग कर सकते हैं।

```
$ resty -e 'local process = require "ngx.process"
ngx.say("process type:", process.type())'
```

आप देखेंगे कि यह `single` परिणाम लौटाता है न कि `worker`, जिसका अर्थ है कि `resty` NGINX को `Worker` प्रोसेस के साथ शुरू करता है, न कि `Master` प्रोसेस के साथ। यह सच है। `resty` कार्यान्वयन में, आप देख सकते हैं कि `Master` प्रोसेस को इस तरह की एक पंक्ति के साथ बंद कर दिया गया है।

```
master_process off;
```

OpenResty ने NGINX को एक `privileged agent` जोड़कर विस्तारित किया है, प्रिविलेज्ड प्रोसेस में निम्नलिखित विशेष सुविधाएँ हैं।

- यह किसी भी पोर्ट को मॉनिटर नहीं करता है, जिसका अर्थ है कि यह बाहरी दुनिया को सेवाएं प्रदान नहीं करता है।
- इसमें `Master` प्रोसेस के समान विशेषाधिकार हैं, जो आमतौर पर `root` उपयोगकर्ता के विशेषाधिकार होते हैं, जो इसे वर्कर प्रोसेस के लिए असंभव कई कार्य करने की अनुमति देता है।
- प्रिविलेज्ड प्रोसेस केवल `init_by_lua` संदर्भ में खोला जा सकता है।
- साथ ही, प्रिविलेज्ड प्रोसेस केवल तभी अर्थपूर्ण होता है जब वे `init_worker_by_lua` संदर्भ में चलते हैं क्योंकि कोई अनुरोध ट्रिगर नहीं होते हैं, और वे `content`, `access` आदि संदर्भों में नहीं जाते हैं।

आइए एक प्रिविलेज्ड प्रोसेस का उदाहरण देखें जो खोला गया है।

```
init_by_lua_block {
    local process = require "ngx.process"

    local ok, err = process.enable_privileged_agent()
    if not ok then
        ngx.log(ngx.ERR, "enables privileged agent failed error:", err)
    end
}
```

इस कोड के साथ प्रिविलेज्ड प्रोसेस को खोलने और OpenResty सेवा शुरू करने के बाद, हम देख सकते हैं कि प्रिविलेज्ड प्रोसेस अब NGINX प्रोसेस का हिस्सा है।

```
nginx: master process
nginx: worker process
nginx: privileged agent process
```

हालांकि, यदि विशेषाधिकार केवल `init_worker_by_lua` चरण के दौरान एक बार चलते हैं, जो एक अच्छा विचार नहीं है, तो हमें प्रिविलेज्ड प्रोसेस को कैसे ट्रिगर करना चाहिए?

हां, उत्तर अभी सिखाए गए ज्ञान में छिपा है। चूंकि यह पोर्ट्स को सुनता नहीं है, अर्थात, इसे टर्मिनल अनुरोधों द्वारा ट्रिगर नहीं किया जा सकता है, इसे नियमित रूप से ट्रिगर करने का एकमात्र तरीका है कि हमने अभी `ngx.timer` का उपयोग किया है:

```
init_worker_by_lua_block {
    local process = require "ngx.process"

    local function reload(premature)
        local f, err = io.open(ngx.config.prefix() .. "/logs/nginx.pid", "r")
        if not f then
            return
        end
        local pid = f:read()
        f:close()
        os.execute("kill -HUP " .. pid)
    end

    if process.type() == "privileged agent" then
         local ok, err = ngx.timer.every(5, reload)
        if not ok then
            ngx.log(ngx.ERR, err)
        end
    end
}
```

उपरोक्त कोड हर 5 सेकंड में मास्टर प्रोसेस को `HUP` सिग्नल भेजने की क्षमता को लागू करता है। स्वाभाविक रूप से, आप इस पर निर्माण करके और अधिक रोमांचक चीजें कर सकते हैं, जैसे डेटाबेस को पोल करना कि क्या प्रिविलेज्ड प्रोसेस के लिए कोई कार्य हैं और उन्हें निष्पादित करना। चूंकि प्रिविलेज्ड प्रोसेस में `root` विशेषाधिकार हैं, यह स्पष्ट रूप से एक "बैकडोर" प्रोग्राम है।

## नॉन-ब्लॉकिंग `ngx.pipe`

अंत में, नॉन-ब्लॉकिंग `ngx.pipe` को देखें, जो Lua के स्टैंडर्ड लाइब्रेरी का उपयोग करके एक बाहरी कमांड लाइन को निष्पादित करता है जो हमारे द्वारा अभी वर्णित कोड उदाहरण में `Master` प्रोसेस को सिग्नल भेजता है।

```
os.execute("kill -HUP " .. pid)
```

स्वाभाविक रूप से, यह ऑपरेशन ब्लॉक करेगा। तो, क्या OpenResty में बाहरी प्रोग्राम को नॉन-ब्लॉकिंग तरीके से कॉल करने का कोई तरीका है? आखिरकार, आप जानते हैं कि यदि आप OpenResty को एक पूर्ण विकास प्लेटफॉर्म के रूप में उपयोग कर रहे हैं और वेब सर्वर के रूप में नहीं, तो यही आपको चाहिए। इसके लिए, `lua-resty-shell` लाइब्रेरी बनाई गई थी, और इसका उपयोग करके कमांड लाइन को कॉल करना नॉन-ब्लॉकिंग है:

```
$ resty -e 'local shell = require "resty.shell"
local ok, stdout, stderr, reason, status =
    shell.run([[echo "hello, world"]])
    ngx.say(stdout)
```

यह कोड `hello world` को लिखने का एक अलग तरीका है, सिस्टम के `echo` कमांड का उपयोग करके आउटपुट को पूरा करना। इसी तरह, आप Lua में `os.execute` कॉल के विकल्प के रूप में `resty.shell` का उपयोग कर सकते हैं।

हम जानते हैं कि `lua-resty-shell` का अंतर्निहित कार्यान्वयन `lua-resty-core` में `ngx.pipe` API पर निर्भर करता है, इसलिए यह उदाहरण `lua-resty-shell` का उपयोग करके `hello world` को प्रिंट करता है, `ngx.pipe` का उपयोग करके, यह इस तरह दिखेगा।

```
$ resty -e 'local ngx_pipe = require "ngx.pipe"
local proc = ngx_pipe.spawn({"echo", "hello world"})
local data, err = proc:stdout_read_line()
ngx.say(data)'
```

उपरोक्त `lua-resty-shell` कार्यान्वयन का अंतर्निहित कोड है। आप इसके उपयोग के बारे में अधिक जानकारी के लिए `ngx.pipe` दस्तावेज़ीकरण और परीक्षण केस देख सकते हैं। इसलिए, मैं यहां इस पर विस्तार से नहीं जाऊंगा।

## सारांश

यही है। हमने आज के लिए मुख्य सामग्री पूरी कर ली है। उपरोक्त सुविधाओं से, हम देख सकते हैं कि OpenResty एक बेहतर NGINX बनाने के साथ-साथ एक सार्वभौमिक प्लेटफॉर्म की दिशा में भी आगे बढ़ने की कोशिश कर रहा है, यह आशा करते हुए कि डेवलपर्स अपनी तकनीकी स्टैक को एकीकृत करने और OpenResty का उपयोग करके अपनी विकास आवश्यकताओं को पूरा करने की कोशिश करें। यह ऑपरेशन और रखरखाव के लिए काफी अनुकूल है क्योंकि जब तक आप इसमें एक OpenResty तैनात करते हैं, रखरखाव लागत कम होती है।

अंत में, मैं आपको एक विचारोत्तेजक प्रश्न छोड़ता हूं। चूंकि कई NGINX `Worker` हो सकते हैं, `timer` प्रत्येक `Worker` के लिए एक बार चलेगा, जो अधिकांश परिदृश्यों में अस्वीकार्य है। हम कैसे सुनिश्चित कर सकते हैं कि `timer` केवल एक बार चले?

अपने समाधान के साथ एक टिप्पणी छोड़ने के लिए स्वतंत्र महसूस करें, और इस लेख को अपने सहयोगियों और दोस्तों के साथ साझा करने के लिए स्वतंत्र महसूस करें ताकि हम एक साथ संवाद और सुधार कर सकें।

Share article link

Share

Related Posts

[![OpenResty FAQ | OpenResty का व्यवहारिक उपयोग कैसे किया जाता है](https://static.api7.ai/uploads/2023/02/12/jbv9M0zi_Hello%20World%20in%20OpenResty%20%283%29.png)](https://api7.ai/learning-center/openresty/faq-5)

## [OpenResty FAQ | OpenResty का व्यवहारिक उपयोग कैसे किया जाता है](https://api7.ai/learning-center/openresty/faq-5)

[![भाग 3: OpenResty का उपयोग करके एक Microservices API Gateway कैसे बनाएं](https://static.api7.ai/uploads/2023/02/07/3XJXY9Jy_45.png)](https://api7.ai/learning-center/openresty/how-to-build-a-microservices-api-gateway-part-3)

## [भाग 3: OpenResty का उपयोग करके एक Microservices API Gateway कैसे बनाएं](https://api7.ai/learning-center/openresty/how-to-build-a-microservices-api-gateway-part-3)

Table of Contents

- [टाइमर टास्क्स](#%E0%A4%9F%E0%A4%BE%E0%A4%87%E0%A4%AE%E0%A4%B0-%E0%A4%9F%E0%A4%BE%E0%A4%B8%E0%A5%8D%E0%A4%95%E0%A5%8D%E0%A4%B8)
- [प्रिविलेज्ड प्रोसेस](#%E0%A4%AA%E0%A5%8D%E0%A4%B0%E0%A4%BF%E0%A4%B5%E0%A4%BF%E0%A4%B2%E0%A5%87%E0%A4%9C%E0%A5%8D%E0%A4%A1-%E0%A4%AA%E0%A5%8D%E0%A4%B0%E0%A5%8B%E0%A4%B8%E0%A5%87%E0%A4%B8)
- [नॉन-ब्लॉकिंग `ngx.pipe`](#%E0%A4%A8%E0%A5%89%E0%A4%A8-%E0%A4%AC%E0%A5%8D%E0%A4%B2%E0%A5%89%E0%A4%95%E0%A4%BF%E0%A4%82%E0%A4%97-ngxpipe)
- [सारांश](#%E0%A4%B8%E0%A4%BE%E0%A4%B0%E0%A4%BE%E0%A4%82%E0%A4%B6)
