2012-10-29 15 views
6

कोई समस्या होने पर जहां मेरी टीम के सदस्यों में से एक PHP में कतार प्रक्रिया कर रहा है। PHP स्क्रिप्ट कमांड लाइन पर चलता है, और प्रत्येक चक्र के बाद खुद को कॉल करता है यह जांचने के लिए कि क्या हमारे डीबी में कोई भी आइटम संसाधित होने की प्रतीक्षा कर रहा है या नहीं। यदि वहां हैं, तो यह स्वयं कांटा जाता है, कतार में आइटम को संसाधित करता है, और दोहराता है। यदि कुछ भी नहीं है, तो यह मर जाता है, और एक क्रॉन नौकरी हर 5 मिनट में कतार को फिर से शुरू करती है।PHP क्यूइंग समस्या - रिडंडेंट प्रक्रिया

कभी-कभी दो प्रक्रियाएं एक ही समय में चलती हैं, एक ही कतार को पकड़ती हैं, और एक दूसरे के रास्ते में आती हैं। मैं जागने की प्रक्रिया में एक जिटर पेश करने की सोच रहा था ताकि प्रक्रिया शुरू होने के बीच यह यादृच्छिक समय हो।

क्या कोई बेहतर तरीका है?

उत्तर

4

जिटर सिर्फ टकराव को कम अनुमानित बनाता है।

डिस्क पर एक म्यूटेक्स रखें। जांचें कि यह दो चक्र पहले से बड़ा है या नहीं। यदि यह है, इसे अनदेखा करें और हटाएं; यह दुर्घटनाग्रस्त कुछ के पीछे छोड़ दिया गया। अन्यथा, पहले से ही चल रहा है, इसलिए जमानत।

2

यदि आपकी कतार में आइटमों को निष्पादित करने की आवश्यकता नहीं है तो आप ऐसा कुछ कर सकते हैं और दोनों प्रक्रियाओं को समानांतर में चलाने के लिए छोड़ दें।

कतार से चुनें अगला काम (स्पष्ट रूप से वाक्य रचना डेटाबेस निर्भर करेगा)

LOCK TABLE queue; 

SELECT * FROM queue WHERE status <> 'INPROGRESS' ORDER BY id LIMIT 1 

UPDATE queue SET status = 'INPROGRESS' WHERE id = ? 

UNLOCK TABLES; 

काम करो तो निशान नौकरी के रूप में पूरा कर लिया या कतार

से हटा दें आप अधर में लटकी अटक नौकरी खोजने के लिए चाहते हैं, आप जॉब स्टोर टाइमस्टैम्प शुरू कर सकते हैं और इसे कतार में वापस रख सकते हैं यदि यह अधिक है तो x mins

0

LOCK TABLE queue; थोड़ा अधिक है क्योंकि यह पूरी तालिका दिखता है इसलिए बिल्कुल कोई सहमति नहीं है। यदि आप फ़ील्ड अपडेट दृष्टिकोण का उपयोग करते हैं तो आपको लॉक की आवश्यकता नहीं है (स्थिति INPROGRESS पर अपडेट की गई है)। एसक्यूएल अद्यतन आपरेशन ताला आंतरिक रूप से करता है, तो कुछ इस तरह समवर्ती काम करने के लिए दिया गया है:

UPDATE queue SET consumer_id='a_consumer_unique_id' status='INPROGRESS' LIMIT 1 

SELECT * FROM queue WHERE consumer_id='a_consumer_unique_id' LIMIT 1 

लेकिन इस दृष्टिकोण साइड इफेक्ट है। हमें ध्वज INPROGRESS या उपभोक्ता_आईडी को बदलना होगा। अगर उपभोक्ता ने एक संदेश देखा (उपभोक्ता_आईडी इसे सेट करता है) और मृत्यु हो गई तो संदेश के साथ क्या होगा? यह उम्र के लिए एक कतार में रहेगा, इसलिए आपको उन परिस्थितियों से निपटने के लिए एक प्रकार की सफाई स्क्रिप्ट की आवश्यकता है।

हम क्या कर सकते हैं संदेश को हमारे रूप में चिह्नित करने, स्मृति में लोड करने और कतार से इसे हटाने के लिए। केवल हम इसे करने के बाद ही हम इसे संसाधित करना शुरू कर देंगे। इस प्रकार enqueue/dbal यह करता है।

यदि आपको पुनर्विक्रय गारंटी की आवश्यकता है तो खरगोश एमक्यू जैसे वास्तविक ब्रोकर का उपयोग करें।

संबंधित मुद्दे