Go कतारों और बैकग्राउंड कार्यों के लिए आदर्श भाषा क्यों है?
\n\nअगर आपने कभी Python या Node.js पर बैकएंड लिखा है, तो आपने शायद इस समस्या का सामना किया होगा: एप्लिकेशन एक रिक्वेस्ट प्रोसेस कर रहा है, और उसी समय आपको एक ईमेल भेजना, एक रिपोर्ट जनरेट करना या अपलोड की गई फ़ाइल को प्रोसेस करना है। अगर आप यह सिंक्रोनस रूप से करते हैं, तो उपयोगकर्ता को इंतज़ार करना पड़ता है। अगर आप इसे एक अलग थ्रेड में करते हैं, तो लॉकिंग और रेस कंडीशन की समस्याएँ शुरू हो जाती हैं।
\n\nGo इस समस्या को सुरुचिपूर्ण और मूल रूप से हल करता है। गोरूटीन (goroutines) और चैनल (channels) अंतर्निहित समानांतरता तंत्र हैं जो Go में कतारों और बैकग्राउंड कार्यों के विकास को सरल और सुरक्षित बनाते हैं। इस लेख में, हम मानक लाइब्रेरी और RabbitMQ जैसे लोकप्रिय टूल दोनों का उपयोग करके बैकग्राउंड प्रोसेसिंग को व्यवस्थित करने का तरीका समझेंगे। आप वास्तविक कोड उदाहरण देखेंगे जिन्हें आप तुरंत अपने प्रोजेक्ट में लागू कर सकते हैं।
\n\nमूल बातें: गोरूटीन और चैनल
\n\nकतारों में गोता लगाने से पहले, आइए बुनियादी बातों को याद करें। गोरूटीन एक हल्का निष्पादन थ्रेड है जो go कीवर्ड से शुरू होता है। चैनल एक टाइप किया गया "पाइपलाइन" है जिसके माध्यम से गोरूटीन एक दूसरे के साथ संवाद करते हैं।
सरल उदाहरण: एसिंक्रोनस ईमेल भेजना
\n\npackage main\n\nimport (\n "fmt"\n "time"\n)\n\nfunc sendEmail(email string) {\n time.Sleep(2 * time.Second) // लंबी ऑपरेशन का अनुकरण\n fmt.Println("Email sent to", email)\n}\n\nfunc main() {\n fmt.Println("Start")\n go sendEmail("user@example.com") // बैकग्राउंड में शुरू\n fmt.Println("Continue processing...")\n time.Sleep(3 * time.Second) // गोरूटीन के पूरा होने की प्रतीक्षा\n}\n\nयहाँ sendEmail बैकग्राउंड में निष्पादित होता है, और मुख्य थ्रेड ब्लॉक नहीं होता है। लेकिन क्या होगा अगर हमें 1000 ईमेल प्रोसेस करने हैं? 1000 गोरूटीन शुरू करना एक अच्छा विचार नहीं है: वे संसाधनों के लिए प्रतिस्पर्धा करना शुरू कर देंगे। यहाँ चैनल और वर्कर पूल पैटर्न मदद करते हैं।
Go में वर्कर पूल पैटर्न
\n\nवर्कर पूल Go में कतारों और बैकग्राउंड कार्यों को व्यवस्थित करने का एक क्लासिक तरीका है। आपके पास वर्कर (गोरूटीन) की एक निश्चित संख्या होती है जो कार्यों के साथ एक चैनल को सुनते हैं। कार्य मुख्य थ्रेड या HTTP हैंडलर से आते हैं।
\n\nवर्कर पूल का कार्यान्वयन
\n\npackage main\n\nimport (\n "fmt"\n "sync"\n "time"\n)\n\ntype Task struct {\n ID int\n Data string\n}\n\nfunc worker(id int, tasks <-chan Task, wg *sync.WaitGroup) {\n defer wg.Done()\n for task := range tasks {\n fmt.Printf("Worker %d processing task %d: %s\\n", id, task.ID, task.Data)\n time.Sleep(1 * time.Second) // काम का अनुकरण\n }\n}\n\nfunc main() {\n const numWorkers = 3\n tasks := make(chan Task, 10) // बफ़र किया गया चैनल\n\n var wg sync.WaitGroup\n\n // वर्कर शुरू करें\n for i := 1; i <= numWorkers; i++ {\n wg.Add(1)\n go worker(i, tasks, &wg)\n }\n\n // कार्य भेजें\n for i := 1; i <= 10; i++ {\n tasks <- Task{ID: i, Data: fmt.Sprintf("Task %d", i)}\n }\n close(tasks) // वर्कर को समाप्त करने के लिए चैनल बंद करें\n\n wg.Wait()\n fmt.Println("All tasks completed")\n}\n\nयह कोड 3 वर्कर बनाता है जो 10 कार्यों को प्रोसेस करते हैं। बफ़र किया गया चैनल आपको बिना ब्लॉक किए कार्य भेजने की अनुमति देता है, जब तक बफ़र भरा न हो। यह पैटर्न वेब एप्लिकेशन में Golang बैकग्राउंड कार्यों के लिए आदर्श है: आप एक रिक्वेस्ट प्राप्त करते हैं, कार्य को चैनल में डालते हैं और तुरंत उपयोगकर्ता को जवाब देते हैं।
\n\nRabbitMQ के साथ Go में कतारें
\n\nवितरित सिस्टम के लिए, मेमोरी में चैनल पर्याप्त नहीं हैं - एक बाहरी कतार स्टोरेज की आवश्यकता है। RabbitMQ सबसे लोकप्रिय मैसेज ब्रोकर में से एक है। आइए देखें कि इसे Go एप्लिकेशन से कैसे कनेक्ट किया जाए।
\n\nइंस्टॉलेशन और कनेक्शन
\n\nपहले amqp लाइब्रेरी इंस्टॉल करें:
go get github.com/rabbitmq/amqp091-go\n\n