परिचय: जावास्क्रिप्ट में कार्य कतारों की आवश्यकता क्यों है?
\nआधुनिक Node.js वेब डेवलपमेंट में अक्सर ऐसे कार्य सामने आते हैं जिन्हें एक HTTP अनुरोध के दायरे में तुरंत पूरा नहीं किया जा सकता। ईमेल न्यूज़लेटर भेजना, PDF रिपोर्ट तैयार करना, इमेज प्रोसेसिंग, बाहरी API के साथ सिंक्रोनाइज़ेशन - इन सभी कार्यों में समय और संसाधनों की आवश्यकता होती है। यदि इन्हें सिंक्रोनस रूप से किया जाए, तो उपयोगकर्ता को उत्तर के लिए बहुत लंबा इंतजार करना पड़ेगा, और सर्वर ओवरलोड हो सकता है।
\nकार्य कतारें (Job Queues) इस समस्या का समाधान करती हैं। वे भारी कार्यों को स्थगित करने, लोड को वितरित करने, विफलता पर पुनः प्रसंस्करण सुनिश्चित करने और सिस्टम को क्षैतिज रूप से स्केल करने की अनुमति देती हैं। इस लेख में, हम जावास्क्रिप्ट (Node.js) में कतारों के साथ काम करने के व्यावहारिक पहलुओं पर चर्चा करेंगे: सिद्धांत से लेकर लोकप्रिय लाइब्रेरीज़ का उपयोग करके कार्यशील कोड लिखने तक।
\n\nकार्य कतारों की मूल अवधारणाएँ
\nकोड पर जाने से पहले, किसी भी कार्य कतार के प्रमुख तत्वों को समझना महत्वपूर्ण है:
\n- \n
- Job (कार्य) — कार्य की एक इकाई जिसे निष्पादित करने की आवश्यकता है। इसमें आमतौर पर डेटा (payload) और मेटा-जानकारी (प्राथमिकता, प्रयास, स्थिति) होती है। \n
- Queue (कतार) — एक डेटा संरचना (अक्सर Redis पर आधारित) जो कार्यों को आगमन के क्रम में संग्रहीत करती है। \n
- Worker (वर्कर) — एक प्रक्रिया या थ्रेड जो कतार से कार्य लेता है और उन्हें निष्पादित करता है। \n
- Producer (प्रोड्यूसर) — सिस्टम का वह भाग जो कतार में कार्य जोड़ता है। \n
- Consumer (कंज़्यूमर) — वर्कर का पर्यायवाची, जो कार्यों को संसाधित करता है। \n
Node.js में, कतारों के साथ काम करने के लिए सबसे लोकप्रिय लाइब्रेरीज़ Bull और Kue हैं। दोनों Redis को मैसेज ब्रोकर के रूप में उपयोग करती हैं। Bull अधिक आधुनिक और प्रदर्शनकारी है, जबकि Kue शुरुआत करने के लिए सरल है। इस लेख में, हम Bull पर ध्यान केंद्रित करेंगे, जिसे प्रोडक्शन के लिए अनुशंसित समाधान माना जाता है।
\n\nBull का उपयोग करके कतार का व्यावहारिक कार्यान्वयन
\nस्थापना और कॉन्फ़िगरेशन
\nशुरू करने के लिए, Redis स्थापित करें (स्थानीय रूप से या Docker के माध्यम से) और प्रोजेक्ट में लाइब्रेरी जोड़ें:
\nnpm install bull\nबुनियादी कतार आरंभीकरण इस प्रकार दिखता है:
\nconst Queue = require('bull');\nconst imageQueue = new Queue('image processing', {\n redis: { host: 'localhost', port: 6379 }\n});\n\nकार्य जोड़ना (Producer)
\nप्रोड्यूसर डेटा और विकल्पों के साथ एक कार्य जोड़ता है:
\napp.post('/upload', async (req, res) => {\n const job = await imageQueue.add({\n imageUrl: req.body.url,\n userId: req.user.id\n }, {\n attempts: 3, // त्रुटि पर प्रयासों की संख्या\n backoff: 5000, // प्रयासों के बीच देरी (ms)\n removeOnComplete: true // सफलता के बाद कार्य हटाएं\n });\n res.json({ jobId: job.id });\n});\n\nकार्य प्रसंस्करण (Worker)
\nवर्कर एक अलग प्रक्रिया (या वही प्रक्रिया, लेकिन एसिंक्रोनस) है जो कतार को सुनता है:
\nimageQueue.process(async (job, done) => {\n try {\n const { imageUrl, userId } = job.data;\n console.log(`उपयोगकर्ता ${userId} के लिए छवि ${imageUrl} का प्रसंस्करण`);\n // यहाँ आपका तर्क: डाउनलोड करें, आकार बदलें, सहेजें\n await processImage(imageUrl);\n done(); // सफल समाप्ति का संकेत\n } catch (error) {\n done(new Error('प्रसंस्करण त्रुटि: ' + error.message));\n }\n});\n\nत्रुटि प्रबंधन और पुनः प्रयास
\nBull स्वचालित रूप से कार्य को दोहराता है यदि वर्कर त्रुटि के साथ समाप्त होता है। आप पुनः प्रयास रणनीति को कॉन्फ़िगर कर सकते हैं:
\nconst job = await imageQueue.add(data, {\n attempts: 5,\n backoff: { type: 'exponential', delay: 2000 }\n});\nआप निगरानी के लिए कतार की घटनाओं को भी सुन सकते हैं:
\nimageQueue.on('completed', (job, result) => {\n console.log(`कार्य ${job.id} पूर्ण हुआ`);\n});\nimageQueue.on('failed', (job, err) => {\n console.error(`कार्य ${job.id} विफल: ${err.mes