PHP टास्क एसिंक्रोनस रूप से चलाएँ


144

मैं कुछ बड़े वेब एप्लिकेशन पर काम करता हूं, और बैकएंड ज्यादातर PHP में है। कोड में कई जगह हैं जहां मुझे कुछ कार्य पूरा करने की आवश्यकता है, लेकिन मैं उपयोगकर्ता को परिणाम के लिए इंतजार नहीं करना चाहता। उदाहरण के लिए, एक नया खाता बनाते समय, मुझे उनका स्वागत ईमेल भेजने की आवश्यकता है। लेकिन जब वे 'समाप्त पंजीकरण' बटन से टकराते हैं, तो मैं उन्हें तब तक इंतजार नहीं करना चाहता जब तक कि ईमेल वास्तव में नहीं भेजा जाता है, मैं बस प्रक्रिया शुरू करना चाहता हूं, और तुरंत उपयोगकर्ता को एक संदेश वापस करना चाहता हूं।

अब तक, कुछ जगहों पर मैं उपयोग कर रहा हूं जो निष्पादन के साथ हैक की तरह महसूस करता है ()। मूल रूप से बातें कर रहे हैं जैसे:

exec("doTask.php $arg1 $arg2 $arg3 >/dev/null 2>&1 &");

जो काम करने के लिए प्रकट होता है, लेकिन मैं सोच रहा हूं कि क्या कोई बेहतर तरीका है। मैं एक ऐसी प्रणाली लिखने पर विचार कर रहा हूं, जो एक MySQL तालिका में कार्यों को कतारबद्ध करता है, और एक अलग लंबे समय तक चलने वाली PHP स्क्रिप्ट जो उस तालिका को एक बार एक बार क्वेरी करती है, और किसी भी नए कार्यों को निष्पादित करती है। यदि मुझे जरूरत हो तो भविष्य में मुझे कई कार्यकर्ता मशीनों के बीच कार्यों को विभाजित करने देने का भी फायदा होगा।

क्या मैं पहिये का फिर से आविष्कार कर रहा हूँ? क्या निष्पादन () हैक या MySQL कतार से बेहतर समाधान है?

जवाबों:


80

मैंने कतारबद्ध दृष्टिकोण का उपयोग किया है, और यह अच्छी तरह से काम करता है क्योंकि आप उस संसाधन को तब तक स्थगित कर सकते हैं जब तक कि आपका सर्वर लोड बेकार नहीं हो जाता है, आपको अपने लोड को बहुत प्रभावी ढंग से प्रबंधित करने देता है यदि आप "कार्य जो आसानी से जरूरी नहीं हैं" को आसानी से विभाजित कर सकते हैं।

अपना खुद का रोल करना बहुत मुश्किल नहीं है, यहाँ कुछ अन्य विकल्प हैं:

  • गियरमैन - यह जवाब 2009 में लिखा गया था, और तब से गियरमैन एक लोकप्रिय विकल्प दिखता है, नीचे टिप्पणियां देखें।
  • यदि आप एक पूर्ण विकसित खुला स्रोत संदेश कतार चाहते हैं तो ActiveMQ
  • ZeroMQ - यह एक बहुत अच्छा सॉकेट लाइब्रेरी है जो वितरित किए गए कोड को लिखने के लिए आसान बनाता है बिना सॉर्टिंग प्रोग्रामिंग के बारे में बहुत अधिक चिंता किए बिना। आप एक एकल होस्ट पर संदेश पंक्तिबद्ध करने के लिए इसका उपयोग कर सकते हैं - आपको बस अपने वेबएप को एक कतार में कुछ धक्का देना होगा जो लगातार चलने वाला कंसोल ऐप अगले उपयुक्त अवसर पर उपभोग करेगा
  • beanstalkd - केवल इस उत्तर को लिखते समय इसे पाया, लेकिन दिलचस्प लग रहा है
  • dropr एक PHP आधारित संदेश कतार परियोजना है, लेकिन सक्रिय रूप से सितंबर 2010 से इसका रखरखाव नहीं किया गया है
  • php-enqueue एक हाल ही में (2017) बनाए रखा गया है, जो विभिन्न कतार प्रणालियों के आसपास रैपर है
  • अंत में, संदेश कतारबद्ध करने के लिए मेमेकैच्ड का उपयोग करने के बारे में एक ब्लॉग पोस्ट

एक और, शायद सरल, दृष्टिकोण ign_user_abort का उपयोग करना है - एक बार जब आप उपयोगकर्ता को पृष्ठ भेजते हैं, तो आप समय से पहले समाप्ति के डर के बिना अपना अंतिम प्रसंस्करण कर सकते हैं, हालांकि इसमें उपयोगकर्ता से पेज लोड को लम्बा करने के लिए दिखने का प्रभाव होता है परिप्रेक्ष्य।


सभी सुझावों के लिए धन्यवाद। Ign_user_abort के बारे में विशिष्ट एक वास्तव में मेरे मामले में मदद नहीं करता है, मेरा पूरा लक्ष्य उपयोगकर्ता के लिए अनावश्यक देरी से बचने के लिए है।
मई'09

2
यदि आप अपने "थैंक यू फॉर रजिस्टरिंग" प्रतिक्रिया में कंटेंट-लेंथ HTTP हेडर सेट करते हैं, तो निर्दिष्ट बाइट्स प्राप्त होने के बाद ब्राउज़र को कनेक्शन बंद कर देना चाहिए। यह अंत उपयोगकर्ता प्रतीक्षा किए बिना सर्वर साइड प्रक्रिया को चला रहा है (यह मानते हुए कि ign_user_abort सेट है)। बेशक, आपको शीर्षकों को प्रस्तुत करने से पहले अपनी प्रतिक्रिया सामग्री के आकार की गणना करने की आवश्यकता होगी, लेकिन छोटी प्रतिक्रियाओं के लिए यह बहुत आसान है।
पीटर

1
गियरमैन ( gearman.org ) एक महान खुला स्रोत संदेश कतार है जो क्रॉस प्लेटफॉर्म है। आप सी, पीएचपी, पर्ल या किसी भी अन्य भाषा में श्रमिकों को लिख सकते हैं। MySQL के लिए Gearman UDF प्लगइन्स हैं और आप PHP या गियरमैन नाशपाती क्लाइंट से Net_Gearman का भी उपयोग कर सकते हैं।
जस्टिन स्वानर्ट

गियरमैन वह होगा जो मैं आज (2015 में) किसी भी कस्टम काम कतार प्रणाली पर सुझाऊंगा।
पीटर

एक अन्य विकल्प एक नोड जेएस सर्वर को एक अनुरोध को संभालने और बीच में एक कार्य के साथ तेजी से प्रतिक्रिया देने के लिए सेट करना है। नोड js स्क्रिप्ट के अंदर कई चीजें एसिंक्रोनस रूप से निष्पादित की जाती हैं जैसे कि http अनुरोध।
जोर्डन

22

जब आप केवल प्रतिक्रिया के लिए प्रतीक्षा किए बिना एक या कई HTTP अनुरोधों को निष्पादित करना चाहते हैं, तो एक सरल PHP समाधान भी है।

कॉलिंग स्क्रिप्ट में:

$socketcon = fsockopen($host, 80, $errno, $errstr, 10);
if($socketcon) {   
   $socketdata = "GET $remote_house/script.php?parameters=... HTTP 1.1\r\nHost: $host\r\nConnection: Close\r\n\r\n";      
   fwrite($socketcon, $socketdata); 
   fclose($socketcon);
}
// repeat this with different parameters as often as you like

Script.php पर, आप पहली पंक्ति में इन PHP कार्यों को लागू कर सकते हैं:

ignore_user_abort(true);
set_time_limit(0);

यह HTTP कनेक्शन बंद होने पर स्क्रिप्ट को बिना समय सीमा के जारी रखने का कारण बनता है।


अगर सेफ मोड में php रन होता है तो set_time_limit का कोई असर नहीं होता
Baptiste Pernet

17

कांटा प्रक्रियाओं का एक अन्य तरीका कर्ल के माध्यम से है। आप अपने आंतरिक कार्यों को एक webservice के रूप में सेट कर सकते हैं। उदाहरण के लिए:

तब आपके उपयोगकर्ता द्वारा एक्सेस की गई स्क्रिप्ट सेवा पर कॉल करती हैं:

$service->addTask('t1', $data); // post data to URL via curl

आपकी सेवा mysql या जो कुछ भी आपको पसंद है, उसके साथ कार्यों की कतार का ट्रैक रख सकती है: यह सब सेवा के भीतर लिपटा हुआ है और आपकी स्क्रिप्ट सिर्फ URL का उपभोग कर रही है। यह आपको किसी अन्य मशीन / सर्वर पर सेवा को स्थानांतरित करने के लिए मुक्त करता है यदि आवश्यक हो (यानी आसानी से स्केलेबल)।

Http प्राधिकरण या एक कस्टम प्राधिकरण योजना (जैसे अमेज़न की वेब सेवाओं) को जोड़ने से आप अपने कार्यों को अन्य लोगों / सेवाओं (यदि आप चाहते हैं) द्वारा उपभोग करने के लिए खोल सकते हैं और आप इसे आगे ले जा सकते हैं और शीर्ष पर एक निगरानी सेवा जोड़ सकते हैं कतार और कार्य की स्थिति।

यह थोड़ा सेट-अप काम करता है लेकिन इसके बहुत सारे लाभ हैं।


1
मुझे यह तरीका पसंद नहीं है क्योंकि यह वेब सर्वर को ओवरलोड करता है
Oved Yavine

7

मैंने एक परियोजना के लिए बीनस्टाकल्ड का उपयोग किया है , और फिर से योजना बनाई है। मैंने पाया है कि यह अतुल्यकालिक प्रक्रियाओं को चलाने का एक शानदार तरीका है।

मैंने इसके साथ कुछ चीजें की हैं:

  • छवि का आकार बदलना - और एक सीएलआई-आधारित PHP स्क्रिप्ट के लिए एक हल्की भरी हुई कतार से गुजरने के साथ, बड़ी (2mb +) छवियों का आकार बदलना ठीक काम करता है, लेकिन एक mod_php उदाहरण के भीतर समान छवियों का आकार बदलने की कोशिश नियमित रूप से मेमोरी-स्पेस मुद्दों में चल रही थी (I PHP प्रक्रिया को 32MB तक सीमित कर दिया, और आकार बदलने से अधिक हो गया)
  • निकट भविष्य की जाँच - बीनस्टॉक ने इसे उपलब्ध करने में देरी की है (यह कार्य केवल X सेकंड के बाद चलाने के लिए उपलब्ध है) - इसलिए मैं किसी घटना के लिए 5 या 10 बार आग लगा सकता हूँ, थोड़ी देर बाद

मैंने एक 'अच्छा' url को डीकोड करने के लिए एक Zend- फ्रेमवर्क आधारित प्रणाली लिखी, इसलिए उदाहरण के लिए, एक छवि को आकार देने के लिए इसे कॉल करेंगे QueueTask('/image/resize/filename/example.jpg')। URL को पहले एक सरणी (मॉड्यूल, कंट्रोलर, एक्शन, पैरामीटर्स) में डिकोड किया गया था, और फिर इंजेक्शन के लिए JSON में ही क्यू में बदल दिया गया।

एक लंबे समय से चल रही क्ली लिपि ने कतार से काम उठाया, इसे चलाया (Zend_Router_Simple के माध्यम से), और यदि आवश्यक हो, तो वेबसाइट PHP के लिए ज्ञापन में जानकारी डाल दें, जब आवश्यक हो।

एक शिकन मैंने यह भी बताई थी कि क्ली-स्क्रिप्ट पुनः आरंभ करने से पहले केवल 50 लूपों के लिए चलती थी, लेकिन अगर यह नियोजित के रूप में पुनः आरंभ करना चाहता था, तो यह तुरंत (बैश-स्क्रिप्ट के माध्यम से चलाया जा रहा है) ऐसा करेगा। अगर वहाँ एक समस्या थी और मैंने किया था exit(0)(के लिए डिफ़ॉल्ट मान exit;या die();) यह पहली सेकंड के एक जोड़े के लिए रुकें होगा।


मुझे बीनस्टॉक की नज़र पसंद है, एक बार वे दृढ़ता जोड़ते हैं मुझे लगता है कि यह सही होगा।
davr

पहले से ही कोडबेस और स्थिर होने में। मैं jobs नामित नौकरियों ’का भी इंतजार कर रहा हूं, इसलिए मैं चीजों को वहां फेंक सकता हूं, लेकिन पता है कि अगर वहां पहले से ही एक है तो इसे जोड़ा नहीं जाएगा। नियमित घटनाओं के लिए अच्छा है।
एलिस्टर बुलमैन

@AlisterBulman क्या आप अधिक जानकारी या उदाहरण दे सकते हैं "लंबे समय तक चलने वाली क्ली स्क्रिप्ट फिर कतार से काम उठाया"। मैं अपने आवेदन के लिए इस तरह की एक स्क्रिप्ट बनाने की कोशिश कर रहा हूँ।
ससी वरना कुमार

7

यदि यह महंगे कार्यों को प्रदान करने का सवाल है, तो php-fpm के समर्थन में, fastcgi_finish_request()फ़ंक्शन का उपयोग करने के लिए क्यों नहीं ?

यह फ़ंक्शन क्लाइंट के लिए सभी प्रतिक्रिया डेटा को फ्लश करता है और अनुरोध को पूरा करता है। यह समय लेने वाले कार्यों को क्लाइंट के कनेक्शन को छोड़ने के बिना प्रदर्शन करने की अनुमति देता है।

आप वास्तव में इस तरह से अतुल्यकालिकता का उपयोग नहीं करते हैं:

  1. पहले अपने सभी मुख्य कोड बनाएं।
  2. निष्पादित करें fastcgi_finish_request()
  3. सभी भारी सामान बनाओ।

एक बार फिर php-fpm की जरूरत है।


5

यहाँ एक सरल वर्ग है जिसे मैंने अपने वेब एप्लिकेशन के लिए कोडित किया है। यह PHP लिपियों और अन्य लिपियों के लिए अनुमति देता है। UNIX और Windows पर काम करता है।

class BackgroundProcess {
    static function open($exec, $cwd = null) {
        if (!is_string($cwd)) {
            $cwd = @getcwd();
        }

        @chdir($cwd);

        if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
            $WshShell = new COM("WScript.Shell");
            $WshShell->CurrentDirectory = str_replace('/', '\\', $cwd);
            $WshShell->Run($exec, 0, false);
        } else {
            exec($exec . " > /dev/null 2>&1 &");
        }
    }

    static function fork($phpScript, $phpExec = null) {
        $cwd = dirname($phpScript);

        @putenv("PHP_FORCECLI=true");

        if (!is_string($phpExec) || !file_exists($phpExec)) {
            if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
                $phpExec = str_replace('/', '\\', dirname(ini_get('extension_dir'))) . '\php.exe';

                if (@file_exists($phpExec)) {
                    BackgroundProcess::open(escapeshellarg($phpExec) . " " . escapeshellarg($phpScript), $cwd);
                }
            } else {
                $phpExec = exec("which php-cli");

                if ($phpExec[0] != '/') {
                    $phpExec = exec("which php");
                }

                if ($phpExec[0] == '/') {
                    BackgroundProcess::open(escapeshellarg($phpExec) . " " . escapeshellarg($phpScript), $cwd);
                }
            }
        } else {
            if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
                $phpExec = str_replace('/', '\\', $phpExec);
            }

            BackgroundProcess::open(escapeshellarg($phpExec) . " " . escapeshellarg($phpScript), $cwd);
        }
    }
}

4

यह वही तरीका है जो मैं पिछले कुछ वर्षों से उपयोग कर रहा हूं और मैंने कुछ भी बेहतर नहीं देखा या पाया नहीं है। जैसा कि लोगों ने कहा है, PHP सिंगल थ्रेडेड है, इसलिए ऐसा बहुत कुछ नहीं है जो आप कर सकते हैं।

मैंने वास्तव में इसमें एक अतिरिक्त स्तर जोड़ा है और यह प्रक्रिया आईडी को प्राप्त कर रहा है। यह मुझे दूसरे पृष्ठ पर पुनर्निर्देशित करने और उपयोगकर्ता को उस पृष्ठ पर बैठने की अनुमति देता है, यदि प्रक्रिया पूरी हो गई है, तो यह देखने के लिए AJAX का उपयोग किया जाता है (प्रक्रिया आईडी अब मौजूद नहीं है)। यह उन मामलों के लिए उपयोगी है जहां स्क्रिप्ट की लंबाई ब्राउज़र को टाइमआउट करने का कारण बनेगी, लेकिन उपयोगकर्ता को अगले चरण से पहले उस स्क्रिप्ट के पूरा होने की प्रतीक्षा करनी होगी। (मेरे मामले में यह CSV के साथ बड़ी ज़िप फ़ाइलों को संसाधित कर रहा था जैसे कि डेटाबेस में 30 000 रिकॉर्ड जोड़ते हैं, जिसके बाद उपयोगकर्ता को कुछ जानकारी की पुष्टि करने की आवश्यकता होती है।)

मैंने रिपोर्ट जनरेशन के लिए भी इसी तरह की प्रक्रिया का इस्तेमाल किया है। मुझे यकीन नहीं है कि मैं ईमेल के रूप में कुछ के लिए "पृष्ठभूमि प्रसंस्करण" का उपयोग करूंगा, जब तक कि धीमी एसएमटीपी के साथ वास्तविक समस्या न हो। इसके बजाय मैं एक कतार के रूप में एक तालिका का उपयोग कर सकता हूं और फिर एक प्रक्रिया है जो कतार के भीतर ईमेल भेजने के लिए हर मिनट चलती है। आपको दो बार या इसी तरह की अन्य समस्याओं के लिए ईमेल भेजने की आवश्यकता होगी। मैं अन्य कार्यों के लिए भी इसी तरह की कतार बनाने की प्रक्रिया पर विचार करूंगा।


1
आप अपने पहले वाक्य में किस विधि का उल्लेख कर रहे हैं?
साइमन ईस्ट

3

PHP एचएएस मल्टीथ्रेडिंग, इसकी डिफ़ॉल्ट रूप से सक्षम नहीं है, एक एक्सटेंशन है जिसे pthreads कहा जाता है जो वास्तव में ऐसा करता है। हालांकि आपको ZTS के साथ संकलित php की आवश्यकता होगी। (थ्रेड सेफ) लिंक्स:

उदाहरण

एक और ट्यूटोरियल

pthreads PECL एक्सटेंशन


2

यह rojoca द्वारा सुझाए अनुसार cURL का उपयोग करने के लिए एक महान विचार है।

यहाँ एक उदाहरण है। जब स्क्रिप्ट बैकग्राउंड में चल रही हो तो आप text.txt की निगरानी कर सकते हैं:

<?php

function doCurl($begin)
{
    echo "Do curl<br />\n";
    $url = 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
    $url = preg_replace('/\?.*/', '', $url);
    $url .= '?begin='.$begin;
    echo 'URL: '.$url.'<br>';
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $result = curl_exec($ch);
    echo 'Result: '.$result.'<br>';
    curl_close($ch);
}


if (empty($_GET['begin'])) {
    doCurl(1);
}
else {
    while (ob_get_level())
        ob_end_clean();
    header('Connection: close');
    ignore_user_abort();
    ob_start();
    echo 'Connection Closed';
    $size = ob_get_length();
    header("Content-Length: $size");
    ob_end_flush();
    flush();

    $begin = $_GET['begin'];
    $fp = fopen("text.txt", "w");
    fprintf($fp, "begin: %d\n", $begin);
    for ($i = 0; $i < 15; $i++) {
        sleep(1);
        fprintf($fp, "i: %d\n", $i);
    }
    fclose($fp);
    if ($begin < 10)
        doCurl($begin + 1);
}

?>

2
यदि स्रोत कोड पर टिप्पणी की जाएगी तो यह वास्तव में मदद करेगा। मुझे नहीं पता कि वहां क्या चल रहा है और कौन से हिस्से उदाहरण हैं और कौन से हिस्से मेरे अपने उद्देश्य के लिए पुन: प्रयोज्य हैं।
थॉमस टेम्पेलमैन

1

दुर्भाग्य से PHP में किसी भी प्रकार की देशी थ्रेडिंग क्षमताएं नहीं हैं। इसलिए मुझे लगता है कि इस मामले में आपके पास कुछ ऐसा कस्टम कोड का उपयोग करने के अलावा कोई विकल्प नहीं है जो आप करना चाहते हैं।

यदि आप PHP थ्रेडिंग सामान के लिए नेट के आसपास खोज करते हैं, तो कुछ लोग PHP पर थ्रेड को अनुकरण करने के तरीकों के साथ आए हैं।


1

यदि आप अपने "थैंक यू फॉर रजिस्टरिंग" प्रतिक्रिया में कंटेंट-लेंथ HTTP हेडर सेट करते हैं, तो ब्राउज़र को बाइट्स की निर्दिष्ट संख्या प्राप्त होने के बाद कनेक्शन बंद कर देना चाहिए। इससे सर्वर साइड प्रक्रिया चल रही है (यह मानते हुए कि ign_user_abort सेट है) इसलिए यह अंतिम उपयोगकर्ता प्रतीक्षा किए बिना काम पूरा कर सकता है।

बेशक, आपको शीर्षकों को रेंडर करने से पहले अपनी प्रतिक्रिया सामग्री के आकार की गणना करने की आवश्यकता होगी, लेकिन यह छोटी प्रतिक्रियाओं के लिए बहुत आसान है (स्ट्रिंग के लिए आउटपुट लिखें, कॉल strlen (), कॉल हेडर (), रेंडर स्ट्रिंग)।

इस दृष्टिकोण से आपको "फ्रंट एंड" कतार का प्रबंधन करने के लिए मजबूर करने का लाभ मिलता है , और हालांकि HTTP चाइल्ड प्रोसेस को एक-दूसरे पर कदम रखने से रोकने के लिए आपको बैक एंड पर कुछ काम करने की आवश्यकता हो सकती है, यह कुछ ऐसा है जो आपको पहले से ही करने की आवश्यकता है , वैसे भी।


यह काम नहीं लगता है। जब मैं उपयोग करता हूं header('Content-Length: 3'); echo '1234'; sleep(5);तब भले ही ब्राउज़र को केवल 3 वर्ण लगते हैं, फिर भी यह प्रतिक्रिया दिखाने से पहले 5 सेकंड तक प्रतीक्षा करता है। मैं क्या खो रहा हूँ?
थॉमस टेम्पेलमैन

@ThomasTempelmann - आपको आउटपुट को वास्तव में तुरंत प्रदान करने के लिए फ्लश () कॉल करने की आवश्यकता है, अन्यथा आउटपुट तब तक बफ़र हो जाएगा जब तक कि आपकी स्क्रिप्ट बाहर नहीं निकलती है या बफर को फ्लश करने के लिए पर्याप्त डेटा STDOUT को भेजा जाता है।
पीटर

मैंने पहले से ही फ्लश करने के कई तरीकों की कोशिश की, एसओ पर यहां पाया गया। कोई मदद नहीं करता। और डेटा गैर-भेजा हुआ प्रतीत होता है, भी, जैसा कि कोई भी बता सकता है phpinfo()। केवल एक चीज जो मैं सोच सकता था, वह यह है कि मुझे पहले न्यूनतम बफर आकार तक पहुंचने की आवश्यकता है, जैसे 256 या इतने बाइट्स।
थॉमस टेम्पेलमैन

@ThomasTempelmann - मुझे आपके प्रश्न या gzip के बारे में मेरे उत्तर में कुछ भी नहीं दिखता है (यह आमतौर पर जटिलता की परतों को जोड़ने से पहले सबसे सरल परिदृश्य को काम करने के लिए समझ में आता है)। यह स्थापित करने के लिए कि सर्वर वास्तव में डेटा भेज रहा है या नहीं, आप ब्राउजर प्लगइन के पैकेट स्निफर का उपयोग कर सकते हैं (जैसे कि फ़िडलर, टेम्परडाटा, आदि)। फिर, यदि आप पाते हैं कि वेबसर्वर वास्तव में फ्लशिंग से बाहर निकलने तक सभी स्क्रिप्ट आउटपुट को पकड़ रहा है, तो आपको अपने वेबसर्वर कॉन्फ़िगरेशन को संशोधित करने की आवश्यकता है (ऐसा कुछ भी नहीं है जो आपके PHP स्क्रिप्ट उस मामले में कर सकता है)।
पीटर

मैं एक आभासी वेब सेवा का उपयोग करता हूं, इसलिए मुझे इसके कॉन्फ़िगरेशन पर थोड़ा नियंत्रण है। मैं अन्य सुझावों को खोजने की उम्मीद कर रहा था कि अपराधी क्या हो सकता है, लेकिन ऐसा लगता है कि आपका जवाब केवल उतना ही सार्वभौमिक रूप से लागू नहीं है जितना यह दिखाई देता है। बहुत सी चीजें गलत हो सकती हैं, जाहिर है। आपका समाधान निश्चित रूप से यहां दिए गए अन्य सभी awers की तुलना में लागू करना बहुत आसान है। बहुत बुरा यह मेरे लिए काम नहीं करता है।
थॉमस टेम्पेलमैन

1

यदि आप पूर्ण विकसित ActiveMQ नहीं चाहते हैं, तो मैं RabbitMQ पर विचार करने की सलाह देता हूं । RabbitMQ हल्के संदेश है जो AMQP मानक का उपयोग करता है ।

मैं एएमक्यूपी आधारित संदेश दलालों तक पहुंचने के लिए एक लोकप्रिय एएमक्यूपी क्लाइंट लाइब्रेरी - पीएचपी-एमकप्लिब में भी देखने की सलाह देता हूं ।


0

मुझे लगता है कि आपको इस तकनीक की कोशिश करनी चाहिए, यह उन सभी पृष्ठों को कॉल करने में मदद करेगा, जिन्हें आप पसंद करते हैं, सभी पेज एक बार में स्वतंत्र रूप से चलेंगे, जो कि अतुल्यकालिक के रूप में प्रत्येक पृष्ठ की प्रतिक्रिया की प्रतीक्षा किए बिना।

cornjobpage.php // मुख्य पृष्ठ

    <?php

post_async("http://localhost/projectname/testpage.php", "Keywordname=testValue");
//post_async("http://localhost/projectname/testpage.php", "Keywordname=testValue2");
//post_async("http://localhost/projectname/otherpage.php", "Keywordname=anyValue");
//call as many as pages you like all pages will run at once independently without waiting for each page response as asynchronous.
            ?>
            <?php

            /*
             * Executes a PHP page asynchronously so the current page does not have to wait for it to     finish running.
             *  
             */
            function post_async($url,$params)
            {

                $post_string = $params;

                $parts=parse_url($url);

                $fp = fsockopen($parts['host'],
                    isset($parts['port'])?$parts['port']:80,
                    $errno, $errstr, 30);

                $out = "GET ".$parts['path']."?$post_string"." HTTP/1.1\r\n";//you can use POST instead of GET if you like
                $out.= "Host: ".$parts['host']."\r\n";
                $out.= "Content-Type: application/x-www-form-urlencoded\r\n";
                $out.= "Content-Length: ".strlen($post_string)."\r\n";
                $out.= "Connection: Close\r\n\r\n";
                fwrite($fp, $out);
                fclose($fp);
            }
            ?>

testpage.php

    <?
    echo $_REQUEST["Keywordname"];//case1 Output > testValue
    ?>

PS: यदि आप url पैरामीटर को लूप के रूप में भेजना चाहते हैं तो इस उत्तर का अनुसरण करें: https://stackoverflow.com/a/41225209/6295712


0

exec()कर्ल का उपयोग कर या सीधे किसी अन्य सर्वर पर सर्वर पर नई प्रक्रियाओं को पैदा करना उस सब को अच्छी तरह से पैमाने पर नहीं करता है, अगर हम निष्पादन के लिए जाते हैं तो आप मूल रूप से अपने सर्वर को लंबे समय तक चलने वाली प्रक्रियाओं के साथ भर रहे हैं जो अन्य गैर-वेब फेसिंग सर्वर द्वारा नियंत्रित किया जा सकता है, और जब तक आप किसी प्रकार के लोड बैलेंसिंग का निर्माण नहीं करते हैं तब तक कर्ल का उपयोग दूसरे सर्वर से होता है।

मैंने कुछ स्थितियों में गियरमैन का उपयोग किया है और मुझे इस तरह के उपयोग के मामले में बेहतर लगता है। मैं मूल रूप से सर्वर द्वारा किए जाने वाले सभी कार्यों की कतार को संभालने के लिए एक एकल नौकरी कतार सर्वर का उपयोग कर सकता हूं और कार्यकर्ता सर्वर को स्पिन कर सकता हूं, जिनमें से प्रत्येक आवश्यकतानुसार कार्यकर्ता प्रक्रिया के कई उदाहरण चला सकता है, और संख्या को स्केल कर सकता है आवश्यकतानुसार काम करने वाले सर्वर और जरूरत न होने पर उन्हें नीचे उतार दें। यह भी कि मुझे जरूरत पड़ने पर कार्यकर्ता प्रक्रियाओं को पूरी तरह से बंद कर दें और जब तक श्रमिक ऑनलाइन वापस न आए तब तक नौकरियों को कतार में रखें।


-4

पीएचपी, एक एकल पिरोया भाषा है तो वहाँ कोई आधिकारिक जिस तरह से यह साथ एक अतुल्यकालिक प्रक्रिया का उपयोग कर के अलावा अन्य शुरू करने के लिए है execया popen। उसके बारे में यहाँ एक ब्लॉग पोस्ट है । MySQL में एक कतार के लिए आपका विचार एक अच्छा विचार है।

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


ईमेल केवल एक उदाहरण था, क्योंकि अन्य कार्य समझाने के लिए अधिक जटिल हैं, और यह वास्तव में सवाल का बिंदु नहीं है। जिस तरह से हम ईमेल भेजते थे, ईमेल कमांड तब तक वापस नहीं आता जब तक कि रिमोट सर्वर मेल को स्वीकार नहीं कर लेता। हमने पाया कि कुछ मेल सर्वरों को मेल स्वीकार करने से पहले लंबी देरी (जैसे 10-20 सेकंड की देरी) के लिए कॉन्फ़िगर किया गया था (शायद स्पैम्बोट्स से लड़ने के लिए), और फिर इन देरी को हमारे उपयोगकर्ताओं पर पारित किया जाएगा। अब, हम भेजे जाने वाले मेल को कतारबद्ध करने के लिए एक स्थानीय मेलस्वरर का उपयोग कर रहे हैं, इसलिए यह विशेष रूप से लागू नहीं होता है, लेकिन हमारे पास समान प्रकृति के अन्य कार्य हैं।
मई'09

उदाहरण के लिए: ssl और पोर्ट 465 के साथ Google Apps Smtp के माध्यम से ईमेल भेजना सामान्य से अधिक समय लेता है।
जिक्सी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.