2011-08-17 15 views
7

मैं वर्तमान में सुविधा सीमित बैंडविड्थ पर काम कर रहा हूँ (मुझे मत पूछो क्यों, अपने मेरा निर्णय नहीं) आवेदन के लिए जो सर्वर के बीच पेलोड के साथ संदेश भेजने के लिए JMS (स्प्रिंग ढांचे JMS और सक्रिय MQ अर्थात्) का उपयोग करें और ग्राहकों।JMS संदेश आकार

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

वहाँ किसी तरह JMS संदेश का आकार प्राप्त करने के लिए कैसे है? जावा में 'sizeof' कार्यान्वयन के अलावा (In Java, what is the best way to determine the size of an object?)

+0

आने वाले संदेश प्रवाह को सीमित क्यों नहीं किया जाएगा - जो ActiveMQ आपको प्रोड्यूसरफ्लो कंट्रोल और मेमोरीलिमिट्स के उपयोग के साथ करने की अनुमति देता है। मुझे यह जानकर उत्सुकता है कि आप आउटगोइंग संदेशों को सीमित क्यों करना चाहते हैं। इसके अलावा - इस प्रकार की चीज़ को आपके ब्रोकर के सामने बैठे किसी भी प्रकार के एप्लिकेशन डिलिवरी कंट्रोलर से बेहतर नियंत्रित नहीं किया जाएगा (मान लीजिए कि आपके पास वह विकल्प भी है)। – whaley

+0

हमारा ग्राहक उत्पादकों से आउटगोइंग बैंडविड्थ को सीमित करना चाहता है (मान लीजिए, ग्राहक के पास 100 एमबीबी बैंडविड्थ है, लेकिन वह केवल 10 एमबीटी का उपयोग करना चाहता है)। ये मुझे पागल कर रहा है। जेएमएस को जितनी जल्दी हो सके संदेश वितरित करने के लिए बनाया जाता है, इसलिए मैं वास्तव में उस मांग को समझ नहीं पा रहा हूं। लेकिन दुख की बात यह है कि यह मेरे फैसले पर नहीं है। – Sorceror

उत्तर

3

क्योंकि जेएमएस संदेशों को प्रक्रिया भेजने में क्रमबद्ध किया गया है, संदेश का आकार प्राप्त करने का सबसे अच्छा तरीका through ObjectOutputStream है।

private int getMessageSizeInBytes(MessageWrapper message) throws IOException { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    ObjectOutputStream oos = new ObjectOutputStream(baos); 
    oos.writeObject(message); 
    oos.close(); 
    return baos.size(); 
} 
4

मुझे नहीं लगता कि आपके क्रमिक आकार को मापने के बजाय जेएमएस संदेश आकार निर्धारित करने के लिए आपके पास कोई गंभीर विकल्प है।

लेकिन आप कुछ अनुकूलन जोड़ने अगर तुम चाहते हो सकता है। कई प्रकार के संदेश हैं (उदा। MapMessage, ObjectMessage, TextMessage)।

पाठ संदेश के आकार अपने पाठ की लंबाई है। मानचित्र संदेश का आकार अपने सभी क्षेत्रों का कुल आकार है। खेतों primitives या java.util.Date हैं, तो उन्हें मापने में कोई समस्या नहीं है। वस्तु संदेश serializable वस्तु मौजूद है, इसलिए आप ByteOutputStream को लिख कर उसके आकार माप सकते हैं।

मुझे लगता है कि अगर आप देरी संदेश भेजने के लिए सबसे JMS प्रदाताओं में से छिपा सुविधा का उपयोग कर रहे हैं टपकाया बाल्टी का उपयोग कर JMS के क्रियान्वयन को सरल बनाया जा सकता है। जब आप इसे ग्रहण करते हैं तो आप संदेश को माप सकते हैं और यह तय कर सकते हैं कि आप ग्राहक को कब प्राप्त करना चाहते हैं। कृपया यहाँ कैसे देरी संदेश भेजने के लिए की जानकारी के लिए पढ़ें: @AlexR से पहले टिप्पणी के अलावा http://alexradzin.blogspot.com/2010/10/send-delayed-jms-messages.html

+0

+1 के बारे में सोचने के लिए अच्छा विचार के लिए +1, धन्यवाद .. – Sorceror

1

, BytesMessage एक getBodyLength() विधि

http://download.oracle.com/javaee/1.4/api/javax/jms/BytesMessage.html#getBodyLength

है और आप शायद ठेठ अनुमान कर सकते हैं सत्र.क्रेट मैसेज() का उपयोग करके बनाए गए कुछ ऑब्जेक्ट्स को कैप्चर करके ट्रांज़िट में हेडर आकार - यानी कोई पेलोड वाला जेएमएस संदेश प्रकार। मुझे लगता है कि बाइट्स मैसेज का उपयोग करके, मुझे बाइट [] में एक पेलोड के साथ सीधे काम करने का लुत्फ उठाना होगा, और यदि बैंडविड्थ महत्वपूर्ण है तो ज़िपऑटपुटस्ट्रीम के माध्यम से संपीड़ित करें। इसके अलावा, जेएमएस संदेश टाइमस्टैम्प और संदेश आईडी को दबाने के लिए संकेत देता है, जो संदेश आकार को कम करने में मदद कर सकता है उदा।

http://download.oracle.com/javaee/1.4/api/javax/jms/MessageProducer.html#setDisableMessageTimestamp%28boolean%29

हालांकि प्रदाताओं इसे समर्थन करने के लिए आवश्यक नहीं कर रहे हैं,

JMS प्रदाता इस संकेत स्वीकार करता है, इन संदेशों को संदेश आईडी अशक्त करने के लिए सेट होनी चाहिए; प्रदाता संकेत पर ध्यान नहीं देता है, तो संदेश आईडी अपनी सामान्य अनूठा मूल्य पर सेट होनी चाहिए

मैं एक बार WebSphere MQ everyplace पर बहुत बैंडविड्थ सीमित JMS के साथ काम किया है, और यह संदेश आकार बहुत छोटे पाने के लिए संभव हो गया था इस तरह - यद्यपि देशी वायरफ्रेम प्रारूप को उस मामले में आकार के लिए भी अनुकूलित किया गया था

+0

बैंडविड्थ महत्वपूर्ण नहीं है, हमारा ग्राहक केवल थ्रूपुट प्रबंधित करना चाहता है। 'GetBodyLength()' के लिए +1 लेकिन मुझे डर है कि यह केवल 'बाइट्समेसेज' उदाहरणों के लिए काम करेगा, जो मुझे लगता है कि मेरे पास नहीं है .. – Sorceror

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