आप परोक्ष दो सवाल पूछा, तो मुझे दोनों का उत्तर दे:
1. मैं अपने AppEngine उदाहरण एकाधिक समवर्ती अनुरोधों को हैंडल करने मिल सकता है?
आप वास्तव में केवल दो काम करने की जरूरत है:
- अपने
appengine-web.xml
फ़ाइल है, जो आप war\WEB-INF
फ़ोल्डर में पा सकते हैं करने के लिए बयान <threadsafe>true</threadsafe>
जोड़ें।
- सुनिश्चित करें कि कोड के अंदर सभी आपके अनुरोध संचालकों वास्तव में धागे की सुरक्षित है, अर्थात अपने
doGet(...)
, doPost(...)
, आदि तरीकों में केवल स्थानीय चर का उपयोग करें या सुनिश्चित करें कि आप वर्ग या वैश्विक चर के इस्तेमाल के सभी सिंक्रनाइज़ करना सुनिश्चित करें।
यह AppEngine उदाहरण सर्वर रूपरेखा है कि अपने कोड धागा सुरक्षित है बता देंगे और आप इसे अलग धागे में सब आपके अनुरोध संचालकों की कई बार फोन करने के लिए एक ही समय में कई अनुरोधों को हैंडल करने की अनुमति दे रहे हैं। नोट: AFAIK, यह एक प्रति-servlet आधार सेट करना संभव नहीं है। तो, सभी आपके servlets को थ्रेड-सुरक्षित होने की आवश्यकता है!
तो, संक्षेप में, आपके द्वारा पोस्ट किया गया निष्पादक कोड पहले से ही प्रत्येक ऐपइंजिन इंस्टेंस के सर्वर कोड में शामिल है, और वास्तव में आपके doGet(...)
विधि को एक अलग थ्रेड के रन विधि के अंदर से कॉल करता है जो AppEngine (या reuses) बनाता है प्रत्येक अनुरोध मूल रूप से doGet()
पहले से ही आपके MyTask()
है।
डॉक्स के प्रासंगिक भाग यहाँ है (हालांकि यह वास्तव में बहुत ज्यादा नहीं कहना है): https://developers.google.com/appengine/docs/java/config/appconfig#Using_Concurrent_Requests
2. पोस्ट इस के लिए उपयोगी कोड (या किसी अन्य) उद्देश्य है?
अपने वर्तमान रूप में ऐपइंजिन आपको अनुरोधों को स्वीकार करने के लिए अपने स्वयं के धागे बनाने और उपयोग करने की अनुमति नहीं देता है। यह केवल आप के अंदर अपने doGet(...)
हैंडलर धागे बनाने के लिए, currentRequestThreadFactory()
विधि आप का उल्लेख का उपयोग कर, लेकिन केवल इस एक अनुरोध के लिए समानांतर प्रसंस्करण करते हैं और समानांतर में एक दूसरे से एक को स्वीकार नहीं करने के लिए (यदि ऐसा होता बाहरdoGet()
) की अनुमति देता है।
नाम currentRequestThreadFactory()
नाम थोड़ा भ्रामक हो सकता है। इसका मतलब यह नहीं है कि यह current
Factory
RequestThreads
, यानी अनुरोधों को संभालने वाले थ्रेड लौटाएगा। इसका मतलब है कि यह Factory
देता है जो currentRequest
के अंदर बना सकता है। इसलिए, दुर्भाग्यवश यह वास्तव में वर्तमान doGet()
निष्पादन के दायरे से बाहर लौटे थ्रेड फैक्ट्री का उपयोग करने की अनुमति भी नहीं है, जैसे कि आप इसके आधार पर एक निष्पादक बनाकर और इसे कक्षा चर में रखते हुए सुझाव दे रहे हैं।
फ्रंटेंड उदाहरणों के लिए, doGet()
कॉल के अंदर बनाए गए किसी भी थ्रेड को तत्काल समाप्त कर दिया जाएगा जब आपका doGet()
विधि रिटर्न होगा। बैकएंड उदाहरणों के लिए, आपको चलने वाले धागे बनाने की अनुमति है, लेकिन चूंकि आपको इन धागे के अंदर अनुरोध स्वीकार करने के लिए सर्वर सॉकेट खोलने की अनुमति नहीं है, फिर भी ये आपको स्वयं को संभालने के अनुरोध को प्रबंधित करने की अनुमति नहीं देंगे।
आप कर सकते हैं और एक ऐप्लिकेशन इंजन सर्वलेट यहाँ के अंदर ऐसा नहीं सकते हैं कि क्या बारे में अधिक जानकारी पा सकते हैं:
The Java Servlet Environment - The Sandbox (विशेष रूप से धागे अनुभाग)
पूर्णता के लिए, आइए देखते हैं आपका कोड "कानूनी" कैसे बनाया जा सकता है:
निम्नलिखित काम करना चाहिए, लेकिन यह आपके कोड के समानांतर में एकाधिक अनुरोधों को संभालने में सक्षम होने के मामले में कोई फर्क नहीं पड़ता है। यह आपको apengine-web.xml में <threadsafe>true</threadsafe>
सेटिंग द्वारा पूरी तरह से निर्धारित किया जाएगा। इसलिए, तकनीकी रूप से, यह कोड केवल वास्तव में अक्षम है और दो धागे में एक अनिवार्य रूप से रैखिक कार्यक्रम प्रवाह को विभाजित करता है।लेकिन यहाँ यह वैसे भी है:
public class MyServlet implements HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) {
ThreadFactory threadFactory = ThreadManager.currentRequestThreadFactory();
Executor executor = Executors.newCachedThreadPool(threadFactory);
Future<MyResult> result = executor.submit(new MyTask(request)); // Fires off request handling in a separate thread
writeResponse(response, result.get()); // Waits for thread to complete and builds response. After that, doGet() returns
}
}
जब से तुम एक अलग थ्रेड उस अनुरोध को आप वर्तमान में संभाल रहे हैं के लिए विशिष्ट है अंदर पहले से ही कर रहे हैं, आप निश्चित रूप से अपने आप को "धागा एक धागा अंदर" बचाने चाहिए और केवल इस के बजाय कार्य करें:
public class MyServlet implements HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) {
writeResponse(response, new MyTask(request).call()); // Delegate request handling to MyTask object in current thread and write out returned response
}
}
या इससे भी बेहतर, कोड को MyTask.call() से doGet() विधि में ले जाएं। -;)
एक तरफ एक साथ 10 सर्वलेट धागे आप का उल्लेख की सीमा के बारे में:
यह एक (अस्थायी) डिजाइन निर्णय है कि और अधिक आसानी से गूगल अपने सर्वर पर लोड को नियंत्रित करने के लिए अनुमति देता है (विशेष रूप से स्मृति है servlets का उपयोग)।
आप यहाँ उन मुद्दों के बारे में अधिक चर्चा पा सकते हैं:
यह विषय भी मुझे से बाहर बिल्ली गुस्सा दिलाना किया गया, के बाद से मैं अल्ट्रा-दुबला सर्वलेट कोड में एक मजबूत आस्तिक हूं, इसलिए समसामयिक अनुरोधों के हजारों नहीं, तो मेरे सामान्य सर्लेट आसानी से सैकड़ों को संभाल सकते हैं। उदाहरण के लिए 10 धागे की इस मनमानी सीमा के कारण अधिक उदाहरणों के लिए भुगतान करना मुझे कम से कम कहने के लिए थोड़ा परेशान है। लेकिन ऊपर दिए गए लिंक पर पढ़ना, ऐसा लगता है जैसे वे इसके बारे में जानते हैं और बेहतर समाधान पर काम कर रहे हैं। तो चलिए देखते हैं कि क्या घोषणाएं गूगल आई/ओ 2013 मई में लाएगा जाने ... :)
+1 - मुझे वास्तव में जिस तरह से आप समस्या के बारे में सोच रहे हैं और जिस तरह से आप समाधान के लिए प्रयास करने की कोशिश कर रहे हैं उसे पसंद करते हैं। लेकिन (un-) सौभाग्य से जीएई इस तरह से काम नहीं करता है और 'currentRequestTreadFactory()' विधि काफी कुछ नहीं करती है जो आप इस नाम के आधार पर उम्मीद कर सकते हैं कि आप इसका नाम कैसे पढ़ सकते हैं। मैंने नीचे एक उत्तर पोस्ट किया है जो उम्मीद है कि विधि नाम में अस्पष्टता को साफ़ कर देगा। (यह वर्तमान रिक्वेस्ट-थ्रेड फैक्ट्री है, वर्तमान-अनुरोध थ्रेड-फैक्ट्री नहीं);) –
जिज्ञासा से बाहर: क्या कोई विशिष्ट विशिष्ट है जिसे आप प्राप्त करने की कोशिश कर रहे हैं? मैं पूछ रहा हूं, क्योंकि थोड़ी देर पहले, मैं एक ही प्रश्न में देख रहा था। मैं जीएई का उपयोग करके कुछ प्रकार की लंबी-मतदान पुश अधिसूचनाओं को लागू करने की उम्मीद कर रहा था, लेकिन यह पता चला कि कई अन्य अतिरिक्त मुद्दे हैं जो इस तरह के कुछ तरीके से आपके रास्ते में आ जाएंगे। जीएई वास्तव में उस तरीके को ट्यून करने की अनुमति देने के मामले में काफी सीमित है जिसमें यह शेड्यूल करता है और अनुरोधों को संभालता है। और इनमें से कुछ सीमाएं थोड़ा अस्पष्ट हैं ... लेकिन, ज़ाहिर है, यही कारण है कि यह इतनी तेज़ और मापनीय हो ... –