अपने PHP साइट को लंबे ऑपरेशनों में 'हैंग' होने से कैसे बचाएं?
\n\nक्या आपने कभी 30 सेकंड तक इंतजार किया है जब तक साइट कन्फर्मेशन ईमेल भेजे? या पीडीएफ रिपोर्ट जनरेट होने पर पेज को 'फ्रीज' होते देखा है? PHP की दुनिया में, जहां हर रिक्वेस्ट आमतौर पर सिंक्रोनस रूप से चलती है, ऐसे काम यूजर एक्सपीरियंस को खराब कर सकते हैं। लेकिन इसका एक पक्का समाधान है — कतारें और बैकग्राउंड टास्क। ये 'भारी' काम को पर्दे के पीछे ले जाते हैं और यूजर को तुरंत दिखाते हैं: 'आपका अनुरोध स्वीकार कर लिया गया!'।
\n\nइस आर्टिकल में हम जानेंगे कि PHP में RabbitMQ, Redis और Gearman जैसे लोकप्रिय टूल्स के साथ कतारें कैसे बनाई जाती हैं। आप रियल कोड उदाहरण देखेंगे, सामान्य गलतियों से बचना सीखेंगे, और आज ही अपने प्रोजेक्ट में बैकग्राउंड प्रोसेसिंग लागू कर सकते हैं।
\n\nPHP में कतारों की ज़रूरत क्यों है?
\n\nPHP पारंपरिक रूप से 'रिक्वेस्ट-रेस्पॉन्स' मॉडल में काम करता है। लेकिन जब 1-2 सेकंड से ज़्यादा समय लेने वाले ऑपरेशन (ईमेल भेजना, इमेज प्रोसेसिंग, रिपोर्ट जनरेशन, वेबहुक) आते हैं, तो यूजर को टाइम-आउट का सामना करना पड़ता है या वे स्पिनर देखते-देखते बोर हो जाते हैं। कतारें इस समस्या को मौलिक रूप से हल करती हैं:
\n\n- \n
- तुरंत रिस्पॉन्स — यूजर को तुरंत जवाब मिलता है, और भारी काम बैकग्राउंड में चला जाता है। \n
- स्केलिंग — आप कोड बदले बिना दर्जनों वर्कर्स को समानांतर चला सकते हैं। \n
- विश्वसनीयता — अगर वर्कर क्रैश हो जाए, तो टास्क कतार में रहेगा और बाद में पूरा होगा। \n
- लोड बैलेंसिंग — पीक लोड बफरिंग के ज़रिए संतुलित हो जाता है। \n
आइए देखते हैं कि तीन सबसे लोकप्रिय तरीकों का उपयोग करके इसे प्रैक्टिस में कैसे लागू किया जाए।
\n\n1. Redis पर कतारें: आसान और तेज़
\n\nRedis सिर्फ कैश नहीं है। डेटा स्ट्रक्चर (लिस्ट, सेट) और Pub/Sub मैकेनिज्म की बदौलत, यह सरल कतारों के लिए एकदम सही है। अगर आपके सर्वर पर पहले से Redis है, तो यह बिना कोई अतिरिक्त सर्विस इंस्टॉल किए बैकग्राउंड टास्क लागू करने का सबसे तेज़ तरीका है।
\n\nउदाहरण: Redis के साथ ईमेल न्यूज़लेटर कतार
\n\nमान लीजिए, यूजर के रजिस्ट्रेशन के बाद एक स्वागत ईमेल भेजना है। कंट्रोलर के अंदर mail() कॉल करने के बजाय, हम बस टास्क को कतार में डाल देते हैं।
\n\nचरण 1. कतार में टास्क जोड़ें (प्रोड्यूसर):
\n\n<?php\n// producer.php\n$redis = new Redis();\n$redis->connect('127.0.0.1', 6379);\n\n$task = json_encode([\n 'type' => 'welcome_email',\n 'user_id' => 42,\n 'email' => 'user@example.com',\n 'created_at' => time()\n]);\n\n// RPUSH एलिमेंट को लिस्ट के अंत में जोड़ता है\n$redis->rPush('email_queue', $task);\necho "टास्क कतार में जोड़ दिया गया\\n";\n?>\n\nचरण 2. वर्कर जो टास्क प्रोसेस करता है (कंज्यूमर):
\n\n<?php\n// worker.php\n$redis = new Redis();\n$redis->connect('127.0.0.1', 6379);\n\necho "वर्कर शुरू, टास्क का इंतज़ार...\\n";\n\nwhile (true) {\n // BLPop तब तक ब्लॉक करता है जब तक कोई एलिमेंट न आए\n $taskData = $redis->blPop('email_queue', 5); // टाइमआउट 5 सेकंड\n \n if ($taskData) {\n $task = json_decode($taskData[1], true);\n \n echo "टास्क प्रोसेस कर रहा हूँ: {$task['type']} {$task['email']} के लिए\\n";\n \n // ईमेल भेजने का अनुकरण\n sleep(2);\n \n // यहाँ असली लॉजिक: mail(), SMTP आदि\n echo "ईमेल यूजर {$task['user_id']} को भेज दिया गया\\n";\n }\n}\n?>\n\nचलाएं:
\nवर्कर को बैकग्राउंड में चलाएं (nohup या Supervisor के ज़रिए):
php worker.php &\n\nअब, जब यूजर रजिस्टर होता है, कंट्रोलर producer.php को कॉल करता है और तुरंत जवाब देता है, जबकि वर्कर ईमेल को शांति से प्रोसेस करता है। Redis गारंटी देता है कि टास्क खोएगा नहीं, भले ही वर्कर अस्थायी रूप से क्रैश हो जाए।
2. RabbitMQ: इंडस्ट्री स्टैंडर्ड
\n\nअगर आपका प्रोजेक्ट बढ़ रहा है