2009-06-25 15 views
5

पर यूडीपी पैकेट भेजने के दौरान कोई बफर स्पेस उपलब्ध नहीं है मेरे पास एक तृतीय पक्ष घटक है जो एक निश्चित स्थिति में बहुत से अलग पते पर बहुत से यूडीपी संदेश भेजने की कोशिश करता है। यह एक विस्फोट है जो तब होता है जब सॉफ्टवेयर शुरू होता है और स्थिति अस्थायी होती है। मुझे वास्तव में यकीन नहीं है कि यह संदेश की सादा राशि या तथ्य यह है कि उनमें से प्रत्येक एक अलग आईपी पते पर जाते हैं।जावा IOException: लिनक्स

वैसे भी, अंतर्निहित प्रोटोकॉल या समस्याग्रस्त घटक को बदलना एक विकल्प नहीं है, इसलिए मैं एक कामकाज की तलाश में हूं। StackTrace इस तरह दिखता है:

java.io.IOException: No buffer space available 
    at java.net.PlainDatagramSocketImpl.send(Native Method) 
    at java.net.DatagramSocket.send(DatagramSocket.java:612) 

यह समस्या (कम से कम) जावा संस्करण 1.6.0_13 और 1.6.0_10 और लिनक्स संस्करणों उबंटू 9.04 और RHEL 4.6 के साथ होता है।

क्या कोई जावा सिस्टम गुण या लिनक्स कॉन्फ़िगरेशन tweaks है जो मदद कर सकता है?

उत्तर

3

लिनक्स में विशेष रूप से गीगाबिट ईथरनेट पर बहुत से संदेश भेजते समय, आपके कर्नेल के लिए स्टॉक पैरामीटर आमतौर पर इष्टतम नहीं होते हैं। आप नेटवर्किंग के लिए लिनक्स कर्नेल बफर आकार को बढ़ा सकते हैं:

echo 1048576 > /proc/sys/net/core/wmem_max 
echo 1048576 > /proc/sys/net/core/wmem_default 
echo 1048576 > /proc/sys/net/core/rmem_max 
echo 1048576 > /proc/sys/net/core/rmem_default 

रूट के रूप में।

या उपयोग sysctl

sysctl -w net.core.rmem_max=8388608 

नेटवर्क विकल्पों में से टन

देखें Linux Network Tuning by IBM और More tuning information

+0

धन्यवाद। उन पैरामीटर के अलावा, मैंने net.ipv4.udp_mem और net.ipv4.udp_wmem_min को भी ट्वीक करने का प्रयास किया। सबसे पहले, मैंने मूल्यों को दोगुना कर दिया, फिर मैंने उन्हें दोबारा दोगुना कर दिया, और अंत में मैंने उन्हें डिफ़ॉल्ट रूप से 10 गुना बड़ा बदल दिया। हालांकि अब तक कुछ भी मदद नहीं मिली है। – auramo

+0

@auramo, आप किस जेवीएम का उपयोग कर रहे हैं? आपके डिस्ट्रो से सूर्य निर्माण या ओपनजेडीके/जेवीएम सामान? मैं आपके डिस्ट्रो के लिए एक का उपयोग करने की सलाह दूंगा, यदि संभव हो तो खुले एक के रूप में यह कम 'सुरक्षित' होगा और कर्नेल/libc के साथ अधिक सटीक इंटरफेसिंग होगा। –

+0

मैं 1.6.0_13 और 1.6.0_10 के सूर्य निर्माण का उपयोग कर रहा हूं। मैं ओपनजेडीके संस्करणों के साथ आसानी से प्रयास कर सकता हूं, लेकिन सूर्य के कार्यान्वयन से बदलना अंतिम उत्पाद के लिए ओपनजेडीके परियोजना के इस बिंदु पर एक बड़ी परेशानी होगी। – auramo

1

थोड़ा जटिल हो सकता है कर रहे हैं, लेकिन जैसा कि मैं जानता हूँ कि, जावा एसपीआई का उपयोग करता है नेटवर्क उप पुस्तकालय के लिए पैटर्न। यह आपको विभिन्न नेटवर्क संचालन के लिए उपयोग किए गए कार्यान्वयन को बदलने की अनुमति देता है। यदि आप ओपनजेडीके का उपयोग करते हैं तो आप कुछ संकेत प्राप्त कर सकते हैं कि आपके कार्यान्वयन के साथ कैसे और क्या लपेटें। फिर, आपके कार्यान्वयन में आप उदाहरण के लिए कुछ नींद के साथ I/O को धीमा कर देते हैं।

या, बस मस्ती के लिए, आप अपने संशोधित कार्यान्वयन के साथ डिफ़ॉल्ट डेटाग्राम सॉकेट को ओवरराइड कर सकते हैं। इसके लिए एक ही पैकेज नाम है और - जैसा कि मुझे पता है - यह डिफ़ॉल्ट जेआरई कक्षा पर प्राथमिकता लेगा। कम से कम इस विधि ने कुछ छोटी गाड़ी 3 पार्टी लाइब्रेरी पर मेरे लिए काम किया।

संपादित करें:

सेवा प्रदाता इंटरफ़ेस एक विधि एक API भीतर ग्राहक और सेवा के कोड को अलग करने के लिए है। यह अलगाव अलग-अलग ग्राहक और विभिन्न प्रदाता कार्यान्वयन की अनुमति देता है। आमतौर पर Impl में समाप्त होने वाले नाम से पहचाना जा सकता है, जैसे कि आपके स्टैक ट्रेस java.net.PlainDatagramSocketImpl में प्रदाता कार्यान्वयन है जहां डेटाग्राम सॉकेट क्लाइंट साइड एपीआई है।

आपने टिप्पणी की कि आप संचार को पूरी तरह से धीमा नहीं करना चाहते हैं। इससे बचने के लिए कई हैक हैं, उदाहरण के लिए अपने कोड में समय मापें और पहले 1-2 मिनट के भीतर संचार को अपनी पहली आने वाली विधि कॉल से शुरू करें। फिर आप नींद छोड़ सकते हैं।

लाइब्रेरी में गलत व्यवहार वर्ग की पहचान करना, जेएडी और इसे ठीक करना एक और विकल्प होगा। फिर पुस्तकालय में मूल वर्ग फ़ाइल को प्रतिस्थापित करें।

+0

क्या आप मुझे बता सकते हैं कि एसपीआई पैटर्न क्या है? मैं 1-2 मिनट, बूट-टाइम विस्फोट से उबरना चाहता हूं। इसके लिए मैं निश्चित रूप से अपने यूडीपी I/O को धीमा नहीं करना चाहता हूं, जो एप्लिकेशन चल रहा है (यह एक सर्वर अनुप्रयोग है) में तेजी से होना चाहिए। – auramo

+0

ठीक है, वह पुराना पैटर्न :-) – auramo

0

मैं वर्तमान में इस समस्या को डेबियन & RHEL दोनों के साथ भी देख रहा हूं। इस बिंदु पर मेरा मानना ​​है कि मैंने इसे एनआईसी और/या एनआईसी चालक को अलग कर दिया है। आपके पास यह हार्डवेयर कॉन्फ़िगरेशन भी है जो इस समस्या को प्रदर्शित करता है? ऐसा लगता है कि यह केवल नए डेल पावरएज सर्वर पर होता है जिसे हमने हाल ही में हासिल किया है जिसमें ब्रॉडकॉम कॉर्पोरेशन नेटएक्सट्रीम II बीसीएम 5708 गिगाबिट ईथरनेट एनआईसी है।

मैं भी पुष्टि कर सकता हूं कि यह एक छोटी सी विंडो में कई अलग-अलग आईपी पते पर आउटबाउंड यूडीपी पैकेट की तेज़ पीढ़ी है। मैंने एक साधारण जावा एप्लिकेशन लिखने का प्रयास किया है जो इसे पुन: उत्पन्न कर सकता है (चूंकि हमारा snmp4j के साथ होता है)। Java IOException: No buffer space available while sending UDP packets on Linux

+0

मेरी समस्या एचपी वर्कस्टेशन के साथ-साथ एक रैक सर्वर पर कई एचडब्ल्यू कॉन्फ़िगरेशन पर हुई। आखिरकार हमने अंतर्निहित घटक (हमारी कंपनी के अंदर एक और टीम से जावा-घटक) हैकिंग समाप्त कर दी, जिसने अत्यधिक नेटवर्क मैसेजिंग को इस मुद्दे को ट्रिगर किया। अब वह घटक बहुत कम यूडीपी अनुरोध/प्रतिक्रिया करता है और समस्या हमारे लिए हल हो जाती है। – auramo

7

मैं अंत में यह निर्धारित किया है कि समस्या क्या है:

संपादित करें मेरा उत्तर यहाँ पर

देखो। जावा IOException भ्रामक है क्योंकि यह "कोई बफर स्पेस उपलब्ध नहीं है" लेकिन मूल मुद्दा यह है कि स्थानीय एआरपी तालिका भर दी गई है। लिनक्स पर, डिफ़ॉल्ट एआरपी टेबल लुकअप 1024 है (फाइल/proc/sys/net/ipv4/hun/default/gc_thresh1,/proc/sys/net/ipv4/hun/default/gc_thresh2,/proc/sys/net/ipv4/पड़ोसियों/डिफ़ॉल्ट/gc_thresh3)।

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

समाधान सरल है, या तो मैंने पहले बताई गई फ़ाइलों को संपादित करके सीमा बढ़ाएं, या अपने सर्वर को अपने गंतव्य पते की तुलना में एक अलग सबनेट में ले जाएं, जिसके बाद लिनक्स बॉक्स अब पड़ोसी एआरपी लुकअप नहीं करेगा (इसके बजाए नेटवर्क पर राउटर द्वारा संभाला जा सकता है)।

+0

पहला स्थान नहीं दिखता है। आपने इसे कैसे क्रैक किया? –

+0

@ ThorbjørnRavnAndersen: मुझे नहीं पता कि अब इसे कैसे देखना है, लेकिन कुछ 8 साल पहले '/ proc/slabinfo' के पास" झुंड "(उदा। एआरपी) प्रविष्टियों के लिए एक अलग प्रविष्टि थी। जब आपको 'ईएनओबीयूएफएस' मिल गया तो आपने यह देखने के लिए 'स्लैबिनफ़ो' को देखा कि वे कौन से बफर थे। आजकल यह शायद 'kmalloc-size' प्रविष्टियों में से कुछ में विलय हो गया है। – ninjalj

0

मुझे यह त्रुटि मिली है जब मैंने डेटाबेस के वाईफ़ाई कनेक्शन का उपयोग करते हुए दो स्थानीय JVM में समेकन क्लस्टर चलाने की कोशिश की .. यदि मैं इसे ईथरनेट का उपयोग करके चलाता हूं - यह अच्छी तरह से चलता है।

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