के साथ यूडीपी सर्वर में खोए गए यूडीपी अनुरोधों के बहुत सारे मैंने नेटटी के साथ एक साधारण यूडीपी सर्वर लिखा जो आसानी से संदेशों (फ्रेम) को लॉग इन करता है। ऐसा करने के लिए, मैंने एक साधारण फ्रेम डिकोडर डिकोडर और एक साधारण संदेश हैंडलर बनाया। मेरे पास एक क्लाइंट भी है जो अनुक्रमिक रूप से और/या समानांतर में एकाधिक अनुरोध भेज सकता है।नेटी
जब मैं अपने क्लाइंट परीक्षक को उदाहरण के लिए कुछ सौ अनुरोधों को अनुक्रमिक रूप से उनके बीच एक छोटी देरी के साथ कॉन्फ़िगर करने के लिए कॉन्फ़िगर करता हूं, तो नेटटी के साथ लिखा गया मेरा सर्वर उन्हें ठीक से प्राप्त करता है। लेकिन फिलहाल मैं अपने क्लाइंट में एक साथ अनुरोधों की संख्या बढ़ाता हूं (उदाहरण के लिए 100) अनुक्रमिक वाले और कुछ दोहराने के साथ, मेरा सर्वर कई अनुरोध खोना शुरू कर देता है। जब मैं उदाहरण के लिए 50000 अनुरोध भेजता हूं, तो मेरे सर्वर को केवल 4 9 000 प्राप्त होते हैं जब केवल सरल चैनल हैंडलर का उपयोग किया जाता है जो प्राप्त संदेश को प्रिंट करता है।
और जब मैं इस हैंडलर के सामने सरल फ्रेम डिकोडर (जो प्रिंट को प्रिंट करता है और इसे अन्य बफर में कॉपी करता है) जोड़ता है, तो सर्वर केवल आधे अनुरोधों को संभालता है !!
मैंने देखा है कि कोई फर्क नहीं पड़ता कार्यकर्ताओं मेरे द्वारा बनाए गए NioDatagramChannelFactory करने के लिए निर्दिष्ट की संख्या, वहाँ हमेशा एक और केवल एक धागा है कि अनुरोधों को प्रबंधित है (मैं सिफारिश Executors.newCachedThreadPool() अन्य पैरामीटर के रूप में उपयोग कर रहा हूँ)।
मैंने जेडीके के साथ आने वाले डेटाग्रामसेट पर आधारित एक और समान सरल यूडीपी सर्वर भी बनाया और यह हर अनुरोध को 0 (शून्य) खोने से पूरी तरह से संभालता है !! जब मैं अपने क्लाइंट में 50000 अनुरोध भेजता हूं (उदाहरण के लिए 1000 धागे के साथ), मुझे अपने सर्वर में 50000 अनुरोध प्राप्त हुए।
क्या मैं नेटटी का उपयोग कर अपने यूडीपी सर्वर को कॉन्फ़िगर करते समय कुछ गलत कर रहा हूं? या शायद नेटटी को ऐसे लोड का समर्थन करने के लिए डिज़ाइन नहीं किया गया है ?? दिए गए कैश थ्रेड पूल द्वारा उपयोग किए जाने वाले केवल एक थ्रेड का उपयोग क्यों किया जाता है (मैंने देखा कि केवल एक धागा और हमेशा जेएमएक्स जेकनसोल में देखकर और आउटपुट लॉग में थ्रेड नाम की जांच करके इसका उपयोग किया जाता है)? मुझे लगता है कि अगर अधिक थ्रेड जहां अपेक्षित थे, तो सर्वर आसानी से ऐसे लोड को संभालने में सक्षम होगा क्योंकि नेटटी का उपयोग न करने पर मैं बिना किसी समस्या के इसे कर सकता हूं!
देखें नीचे मेरी प्रवर्तन कोड:
...
lChannelfactory = new NioDatagramChannelFactory(Executors.newCachedThreadPool(), nbrWorkers);
lBootstrap = new ConnectionlessBootstrap(lChannelfactory);
lBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
@Override
public ChannelPipeline getPipeline()
{
ChannelPipeline lChannelPipeline = Channels.pipeline();
lChannelPipeline.addLast("Simple UDP Frame Dump DECODER", new SimpleUDPPacketDumpDecoder(null));
lChannelPipeline.addLast("Simple UDP Frame Dump HANDLER", new SimpleUDPPacketDumpChannelHandler(lOuterFrameStatsCollector));
return lChannelPipeline;
}
});
bindChannel = lBootstrap.bind(socketAddress);
...
और मेरे विकोडक में विधि डिकोड() की सामग्री:
protected Object decode(ChannelHandlerContext iCtx, Channel iChannel, ChannelBuffer iBuffer) throws Exception
{
ChannelBuffer lDuplicatedChannelBuffer = null;
sLogger.debug("Decode method called.");
if (iBuffer.readableBytes() < 8) return null;
if (outerFrameStatsCollector != null) outerFrameStatsCollector.incrementNbrRequests();
if (iBuffer.readable())
{
sLogger.debug(convertToAsciiHex(iBuffer.array(), iBuffer.readableBytes()));
lDuplicatedChannelBuffer = ChannelBuffers.dynamicBuffer(iBuffer.readableBytes());
iBuffer.readBytes(lDuplicatedChannelBuffer);
}
return lDuplicatedChannelBuffer;
}
और messageReceived की सामग्री() मेरे हैंडलर में विधि:
public void messageReceived(final ChannelHandlerContext iChannelHandlerContext, final MessageEvent iMessageEvent) throws Exception
{
ChannelBuffer lMessageBuffer = (ChannelBuffer) iMessageEvent.getMessage();
if (outerFrameStatsCollector != null) outerFrameStatsCollector.incrementNbrRequests();
if (lMessageBuffer.readable())
{
sLogger.debug(convertToAsciiHex(lMessageBuffer.array(), lMessageBuffer.readableBytes()));
lMessageBuffer.discardReadBytes();
}
}
आप जानते हैं कि यूडीपी कोई वितरण गारंटियों का अधिकार है कर रहे हैं? –
हां, मुझे पता है कि ऐसी कोई डिलीवरी गारंटी नहीं है, लेकिन मेरे लोड परीक्षण स्थानीय रूप से किए जाते हैं और मैं नेटी सामान की बजाय डेटाग्राम सॉकेट का उपयोग करके अपने सरल सर्वर के साथ कुछ भी नहीं खोता हूं। मैं वर्तमान में वायरशर्क के साथ अनुरोधों का विश्लेषण करने के लिए भी पुष्टि कर रहा हूं कि एक मामले में (नेटटी के बिना) कुछ भी नहीं खो गया है और नेटटी का उपयोग करते समय पैकेट खो गए हैं। – The4Summers
@ The4Summers यदि आप देख सकते हैं कि नेटटी के साथ पैकेट खो रहे हैं, नेटटी आने वाले पैकेट को पर्याप्त रूप से पर्याप्त संसाधित नहीं कर रहा है, या आप नहीं हैं, इसलिए सॉकेट प्राप्त बफर भर रहा है, इसलिए आने वाले पैकेट को त्याग दिया जा रहा है, कहीं और नहीं है जाना। अपनी प्राप्त करने की गति बढ़ाएं या अपना प्रेषण धीमा करें। – EJP