2010-02-18 15 views
37

मेरे पास लिनक्स पर जावा ऐप है जो यूडीपी सॉकेट खोलता है और संदेशों के लिए इंतजार करता है।लिनक्स यूडीपी बफर उपलब्ध स्थान की निगरानी कैसे करें?

भारी भार के तहत कुछ घंटों के बाद, एक पैकेट नुकसान होता है, यानी पैकेट को कर्नेल द्वारा प्राप्त किया जाता है, लेकिन मेरे ऐप द्वारा नहीं (हम स्निफ़ेर में खोए गए पैकेट देखते हैं, हम नेटस्टैट में खोए गए यूडीपी पैकेट देखते हैं, हम डॉन ' हमारे ऐप लॉग में उन पैकेट को नहीं देखते हैं)।

हमने सॉकेट बफर को बढ़ाने की कोशिश की लेकिन इससे मदद नहीं मिली - हमने बाद में पैकेट खोना शुरू कर दिया, लेकिन यह है।

डीबगिंग के लिए, मैं जानना चाहता हूं कि किसी भी पल में ओएस udp बफर कितना भरा है। गुगल, लेकिन कुछ भी नहीं मिला। क्या आप मेरी मदद कर सकते हैं?

पीएस दोस्तों, मुझे पता है कि यूडीपी अविश्वसनीय है। हालांकि - मेरे कंप्यूटर को सभी यूडीपी संदेश प्राप्त होते हैं, जबकि मेरा ऐप उनमें से कुछ उपभोग करने में असमर्थ है। मैं अपने ऐप को अधिकतम तक अनुकूलित करना चाहता हूं, यही सवाल है। धन्यवाद।

उत्तर

27

लिनक्स /proc/net/udp और /proc/net/udp6 फ़ाइलें प्रदान करता है, जिसमें सभी खुले यूडीपी सॉकेट (क्रमशः आईपीवी 4 और आईपीवी 6 के लिए) सूचीबद्ध हैं। उनमें से दोनों में, कॉलम tx_queue और rx_queue बाइट्स में आउटगोइंग और आने वाली कतार दिखाते हैं।

यदि सबकुछ अपेक्षित रूप से काम कर रहा है, तो आप आमतौर पर उन दो स्तंभों में शून्य से अलग मूल्य नहीं देखेंगे: जैसे ही आपका एप्लिकेशन पैकेट उत्पन्न करता है, उन्हें नेटवर्क के माध्यम से भेजा जाता है, और जैसे ही ये पैकेट नेटवर्क से आते हैं आवेदन उठ जाएगा और उन्हें प्राप्त होगा (recv कॉल तुरंत लौटाता है)। यदि आपके एप्लिकेशन में सॉकेट खुला है तो rx_queue ऊपर जा सकता है लेकिन डेटा प्राप्त करने के लिए recv का आविष्कार नहीं कर रहा है, या यदि यह पर्याप्त डेटा को पर्याप्त तेज़ी से संसाधित नहीं कर रहा है।

+2

धन्यवाद rx_queue के लिए, आराम के लिए - अद्यतन) –

+1

@Juliano कौन कहता है कि वह उपयोग करने के लिए प्रोटोकॉल चुनाव कर सकते हैं? हो सकता है कि वह मौजूदा ग्राहकों की सेवा के लिए एक udp आधारित प्रोटोकॉल को कार्यान्वित कर रहा हो। – steffen

+2

पोस्टर यूडीपी आंकड़ों की निगरानी के बारे में जानना चाहता है, न कि प्रोटोकॉल का उपयोग करने के विचारों के लिए। पहली बार यह पहचानकर कि परतों के नुकसान में कहां हो रहा है, कोई एक फिक्स पर काम कर सकता है। – RickS

-1

प्रक्रिया सरल है:

  1. अगर वांछित, आवेदन प्रक्रिया को रोक दें।

  2. यूडीपी सॉकेट खोलें। यदि आवश्यक हो तो आप /proc/<PID>/fd का उपयोग कर चल रहे प्रक्रिया से इसे छीन सकते हैं। या आप इस कोड को एप्लिकेशन में ही जोड़ सकते हैं और इसे एक सिग्नल भेज सकते हैं - इसमें पहले से ही सॉकेट खुलेगा।

  3. कॉल recvmsg जितनी जल्दी हो सके एक तंग लूप में कॉल करें।

  4. गणना करें कि आपको कितने पैकेट/बाइट मिले हैं।

यह वर्तमान में buffered किसी भी डेटाग्राम को त्याग देगा, लेकिन यदि यह आपके आवेदन को तोड़ देता है, तो आपका आवेदन पहले से ही टूट गया था।

+0

मैं इस जवाब को कम करने वाला था, लेकिन दूसरे विचार पर यह उल्लसित है। मैं तो बस उम्मीद है कि कोई भी इस :) – Navin

4

rx_queue आपको किसी दिए गए पल में कतार की लंबाई बताएगा, लेकिन यह आपको नहीं बताएगा कि कतार कितनी पूर्ण है, यानी हाईवाटर चिह्न। इस मान की लगातार निगरानी करने का कोई तरीका नहीं है, और इसे प्रोग्रामेटिक रूप से प्राप्त करने का कोई तरीका नहीं है (How do I get amount of queued data for UDP socket? देखें)।

कतार की लंबाई की निगरानी करने का एकमात्र तरीका यह है कि कतार को अपने स्वयं के कार्यक्रम में ले जाना है। दूसरे शब्दों में, दो थ्रेड शुरू करें - कोई सॉकेट जितना तेज़ हो सके उतना तेज़ पढ़ रहा है और डेटाग्राम को आपकी कतार में डंप कर रहा है; और दूसरा आपका प्रोग्राम इस कतार से खींच रहा है और पैकेट को संसाधित कर रहा है। यह निश्चित रूप से मानता है कि आप प्रत्येक थ्रेड को एक अलग CPU पर आश्वस्त कर सकते हैं। अब आप अपनी खुद की कतार की लंबाई की निगरानी कर सकते हैं और हाईवाटर चिह्न का ट्रैक रख सकते हैं।

46

यूडीपी एक पूरी तरह व्यवहार्य प्रोटोकॉल है। यह सही नौकरी के लिए सही उपकरण का वही पुराना मामला है!

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

इसे छोटे विस्फोटों के लिए सहन किया जा सकता है। कतार ठीक वही करता है जो इसे करने के लिए किया जाता है - कतार डेटाग्राम जब तक आप तैयार न हों। लेकिन अगर औसत आगमन दर नियमित रूप से कतार में बैकलॉग का कारण बनती है, तो यह आपके कार्यक्रम को फिर से डिजाइन करने का समय है। यहां दो मुख्य विकल्प हैं: चालाक प्रोग्रामिंग तकनीकों के माध्यम से विलुप्त प्रसंस्करण समय को कम करें, और/या अपने कार्यक्रम को बहु-थ्रेड करें। आपके कार्यक्रम के कई उदाहरणों में संतुलित संतुलन भी नियोजित किया जा सकता है।

जैसा कि बताया गया है, लिनक्स पर आप यूपीपी के बारे में स्थिति प्राप्त करने के लिए प्रो फाइल सिस्टम की जांच कर सकते हैं। उदाहरण के लिए, अगर मैं /proc/net/udp नोड cat, मैं कुछ इस तरह मिलती है: इस से

$ cat /proc/net/udp 
    sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops    
    40: 00000000:0202 00000000:0000 07 00000000:00000000 00:00000000 00000000  0  0 3466 2 ffff88013abc8340 0   
    67: 00000000:231D 00000000:0000 07 00000000:0001E4C8 00:00000000 00000000 1006  0 16940862 2 ffff88013abc9040 2237  
122: 00000000:30D4 00000000:0000 07 00000000:00000000 00:00000000 00000000 1006  0 912865 2 ffff88013abc8d00 0   

, मैं देख सकता है कि उपयोगकर्ता आईडी 1006 के स्वामित्व वाले एक सॉकेट, पोर्ट पर ध्यान दे रहा है 0x231D (8989) और प्राप्त होने वाले कतार लगभग 128 केबी है। चूंकि 128 केबी मेरे सिस्टम पर अधिकतम आकार है, यह मुझे बताता है कि आने वाले डेटाग्राम को बनाए रखने में मेरा प्रोग्राम बेहद कमजोर है। अब तक 2237 बूंदें हुई हैं, जिसका अर्थ है कि यूडीपी परत सॉकेट कतार में कोई और डेटाग्राम नहीं डाल सकती है, और उन्हें छोड़ना चाहिए।

आप जैसे समय के साथ अपने कार्यक्रम के व्यवहार देख सकते हैं का उपयोग करते हुए:

watch -d 'cat /proc/net/udp|grep 00000000:231D' 

भी ध्यान दें कि netstat कमांड एक ही बात के बारे में करता है: netstat -c --udp -an

मेरी weenie कार्यक्रम के लिए मेरे समाधान, बहु धागा करने के लिए किया जाएगा।

चीयर्स!

+0

कैसे आप अपने सिस्टम के अधिकतम udp कतार आकार में जाना जाता है 128KB है को लागू करने की कोशिश की? – Chinaxing

+2

@ चाइनाक्सिंग 'बिल्ली/proc/sys/net/core/rmem_max' – wakjah

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