2012-12-05 28 views
22

का उपयोग कर ईसी 2 पर चल रहे जावा इंस्टेंस से कनेक्ट करने के लिए हमें अमेज़ॅन के ईसी 2 क्लस्टर में चल रहे हमारे जावा एप्लिकेशन से कनेक्ट करने में समस्या हो रही है। हमने निश्चित रूप से "जेएमएक्स पोर्ट" (जो आमतौर पर आरएमआई रजिस्ट्री पोर्ट है) और सर्वर पोर्ट (जो अधिकांश काम करता है) दोनों को सुरक्षा-समूह में प्रश्नों के उदाहरणों के लिए अनुमति दी है। Jconsole कनेक्ट करता है लेकिन लटका लगता है और कभी भी कोई जानकारी नहीं दिखाता है। बंदरगाहों कोजेएमएक्स

  • Telnets कनेक्ट लेकिन कोई जानकारी प्रदर्शित होता है:

    हम निम्नलिखित की तरह कुछ के साथ हमारे जावा चल रहे हैं:

    java -server -jar foo.jar other parameters here > java.log 2>&1 
    

    हम कोशिश की है।

  • हम उदाहरण के लिए jconsole चला सकते हैं उदाहरण के लिए रिमोट-एक्स 11 एसएसएच का उपयोग करके और यह जानकारी को जोड़ता है और दिखाता है। तो जेआरई स्थानीय रूप से निर्यात कर रहा है।
  • सुरक्षा समूह में सभी बंदरगाहों को खोलना। Weeee।
  • यह सुनिश्चित करने के लिए tcpdump का उपयोग करके यातायात अन्य बंदरगाहों पर नहीं जा रहा है।
  • इसे स्थानीय रूप से सिमुलेट करना। हम हमेशा हमारे स्थानीय जेआरई या उसी एप्लिकेशन पैरामीटर का उपयोग करके हमारे नेटवर्क पर कहीं और चल रहे लोगों से जुड़ सकते हैं।

java -version आउटपुट:

OpenJDK Runtime Environment (IcedTea6 1.11.5) (amazon-53.1.11.5.47.amzn1-x86_64) 
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode) 

एक के रूप में एक तरफ, हम मेरी Simple JMX पैकेज जो हमें स्थापित करने के लिए अनुमति देता है का उपयोग कर रहे दोनों RMI रजिस्ट्री और सर्वर बंदरगाहों जो आम तौर पर अर्द्ध बेतरतीब ढंग से RMI द्वारा चुना जाता है रजिस्ट्री। आप निम्न JMX यूआरआई की तरह कुछ के साथ इस के लिए मजबूर कर सकते हैं:

service:jmx:rmi://localhost:" + serverPort + "/jndi/rmi://:" + registryPort + "/jmxrmi" 

इन दिनों हम दोनों सर्वर और रजिस्ट्री के लिए एक ही बंदरगाह का उपयोग करें। अतीत में हमने सुरक्षा-समूह नियमों को आसान बनाने के लिए सर्वर-पोर्ट के लिए रजिस्ट्री-पोर्ट और X+1 के रूप में X का उपयोग किया है। आप रजिस्ट्री-पोर्ट से jconsole या जो भी जेएमएक्स क्लाइंट आप उपयोग कर रहे हैं उससे कनेक्ट हैं।

उत्तर

35

हमें अमेज़ॅन के ईसी 2 क्लस्टर में चल रहे हमारे जावा एप्लिकेशन से कनेक्ट करने में समस्या हो रही है।

यह पता चला है कि समस्या दो गायब सेटिंग्स का संयोजन था। पहली बार जेआरई आईपीवी 4 और v6 पसंद करने के लिए मजबूर करता है। यह जरूरी हो गया था (मुझे लगता है) के बाद से हम एक v4 पते के माध्यम से इसे करने के लिए कनेक्ट करने के लिए कोशिश कर रहे हैं:

-Djava.net.preferIPv4Stack=true 

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

-Djava.rmi.server.hostname=ec2-107-X-X-X.compute-1.amazonaws.com 

चाल, अगर आप अपने EC2 उदाहरणों को स्वचालित करने की कोशिश कर रहे (और क्यों नरक तुम नहीं), कैसे रनटाइम पर इस पते मिल रहा है। है कि आप हमारे आवेदन बूट लिपि में निम्नलिखित की तरह कुछ डाल करने के लिए की जरूरत है ऐसा करने के लिए: wget आदेश में

# get our _external_ hostname 
RMI_HOST=`wget -q -O - http://169.254.169.254/latest/meta-data/public-hostname` 
... 
java -server \ 
    -Djava.net.preferIPv4Stack=true -Djava.rmi.server.hostname=$RMI_HOST \ 
    -jar foo.jar other parameters here > java.log 2>&1 

रहस्यमय 169.254.169.254 आईपी उपरोक्त जानकारी है कि EC2 उदाहरण खुद के बारे में अनुरोध कर सकते हैं प्रदान करता है। मुझे निराश है कि यह में टैग शामिल हैं जो केवल प्रमाणित कॉल में उपलब्ध हैं।

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

उम्मीद है कि यह किसी और की मदद करेगा। आज मुझे 3 घंटे खर्च करो।

How to close rmiregistry running on particular port?

:

इस उत्तर ताकि आप उन्हें में EC2 सुरक्षा समूह को ब्लॉक कर सकते नामित बंदरगाहों पर सर्वर और RMI रजिस्ट्री शुरू करने के लिए अपने JMX सर्वर के लिए मजबूर करने के लिए, को देखने के संपादित करें:

हमें अभी भी यह समस्या फिर से उत्पन्न हुई थी। ऐसा लगता है कि जावा जेएमएक्स कोड बॉक्स के होस्टनाम पर कुछ होस्टनाम लुकअप कर रहा है और जेएमएक्स कनेक्शन को जोड़ने और सत्यापित करने के लिए उनका उपयोग कर रहा है।

यह समस्या एक आवश्यकता है कि बॉक्स के स्थानीय होस्टनाम को बॉक्स के स्थानीय-आईपी को हल करना चाहिए। उदाहरण के लिए, यदि आपके /etc/sysconfig/network में HOSTNAME=server1.foobar.com है तो यदि आप server1.foobar.com पर DNS लुकअप करते हैं, तो आपको 10-नेट वर्चुअल एड्रेस प्राप्त करना चाहिए। हम अपनी खुद की /etc/hosts फ़ाइल बना रहे थे और फ़ाइल से स्थानीय होस्ट का होस्टनाम गायब था। इससे हमारे एप्लिकेशन स्टार्टअप पर या फिर स्टार्टअप पर रोक नहीं पाए।

अन्त में

एक अपनी JMX निर्माण को आसान बनाने के लिए रास्ता मेरी SimpleJMX package उपयोग करने के लिए है।

+2

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

+0

धन्यवाद @ विल्ग्लिन। मैं अपने उदाहरण में अपनी एक्सेस/गुप्त कुंजी जोड़ने के लिए टैग _without_ प्राप्त करने की उम्मीद कर रहा था। हाँ, अब हम UserData का उपयोग करते हैं, लेकिन मैं इसके बजाय 'key = value' प्रकार की सामग्री होगी ताकि ops टाइपो नहीं बनाये। – Gray

+2

एक ही उदाहरण मेटाडेटा चैनल पर स्वचालित रूप से एडब्ल्यूएस प्रमाण-पत्रों को उत्पन्न करने और वितरित करने के लिए एक तंत्र है: देखें [ईसी 2 उदाहरणों के लिए आईएएम भूमिकाएं] (http://aws.typepad.com/aws/2012/06/iam-roles-for-ec2 -instances सरलीकृत-सुरक्षित का उपयोग करने के लिए एडब्ल्यूएस-सेवा-API- से-ec2.html)। आप EC2 DescribeInstances एक्सेस तक सीमित भूमिका निभा सकते हैं, जिससे आप क्रेडेंशियल्स प्रबंधन से पागल होने के बिना सबकुछ स्वचालित कर सकते हैं। – willglynn

1

ग्रे द्वारा दिए गए उत्तर ने मेरे लिए काम किया, हालांकि मुझे लगता है कि मुझे टीसीपी बंदरगाह 0 से 65535 खोलना है या मुझे अंदर नहीं जाना है। मैं सोचता हूं कि आप मुख्य जेएमएक्स पोर्ट से कनेक्ट कर सकते हैं, और फिर एक और सौंपा जाओ। मुझे लगता है कि this blog post से जो हमेशा मेरे लिए अच्छा काम करता है।

+0

हम _not_ को @Eric करना है। हमारे पास सिर्फ आरएमआई पोर्ट है और जेएमएक्स सर्वर पोर्ट खोला गया है। जब आप अपना जेएमएक्स सर्वर बनाते हैं तो आपको दोनों बंदरगाहों को निर्दिष्ट करने की आवश्यकता होती है। एक तरफ के रूप में, सरल जेएमएक्स पैकेज आपके लिए बहुत आसानी से करता है: http://256.com/sources/simplejmx/ – Gray

+0

यह उत्तर देखें: http://stackoverflow.com/questions/8386001/how-to-close-rmiregistry- रन-ऑन-स्पेशल-पोर्ट/8386052 # 8386052 – Gray

+0

ग्रे, यह दिलचस्प है ... हालांकि, मैं कोडा हेल मेट्रिक्स लाइब्रेरी का उपयोग कर रहा हूं, जो जेएमएक्स स्थापित करने में अपना जादू है .... मुझे आश्चर्य है कि यह मुझे दे सकता है क्या सरलjmx करता है? –

11

दूसरे उत्तर Why does JMX connection to Amazon EC2 fail? पर, यहां कठिनाई यह है कि डिफ़ॉल्ट रूप से आरएमआई पोर्ट को यादृच्छिक रूप से चुना जाता है, और ग्राहकों को जेएमएक्स और आरएमआई पोर्ट दोनों तक पहुंच की आवश्यकता होती है। यदि आप jdk7u4 या बाद में चल रहे हैं, तो आरएमआई पोर्ट को ऐप प्रॉपर्टी के माध्यम से निर्दिष्ट किया जा सकता है।शुरू निम्नलिखित JMX सेटिंग्स के साथ अपने सर्वर मेरे लिए काम किया:

-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=9999 
-Dcom.sun.management.jmxremote.rmi.port=9998 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.authenticate=false 
-Djava.rmi.server.hostname=<public EC2 hostname> 
प्रमाणीकरण के साथ

:

प्रमाणीकरण के बिना

-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=9999 
-Dcom.sun.management.jmxremote.rmi.port=9998 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.authenticate=true 
-Dcom.sun.management.jmxremote.password.file=/path/to/jmxremote.password 
-Djava.rmi.server.hostname=<public EC2 hostname> 

मैं भी खोला बंदरगाहों 9998-9999 के लिए EC2 सुरक्षा समूह में मेरी उदाहरण।

+0

यदि आपके इंस्टेंस में सार्वजनिक ईसी 2 होस्टनाम नहीं है (उदाहरण के लिए इसे ईएलबी के पीछे छिपाएं) और आप सिर्फ जेएमएक्स को आंतरिक रूप से काम करना चाहते हैं, तो ऊपर वर्णित मार्क के रूप में जेएमएक्स बंदरगाहों और सुरक्षा समूह को सेट करें, और उदाहरण होस्टनाम को रखें java.rmi.server.hostname के लिए। आपको पता चलेगा कि उदाहरण इस प्रकार स्थापित किया गया है यदि आप @ ग्रे के उत्तर में सूचीबद्ध/मेटा-डेटा/सार्वजनिक-होस्टनाम/एंडपॉइंट को कॉल करते हैं और आपको खाली रिक्त स्थान मिलता है। – Matt

1

एक ssh सुरंगों

  1. का उपयोग करके अलग दृष्टिकोण थोड़ा JVM के लिए निम्न झंडे दर्रा

-Dcom.sun.management.jmxremote.port=1099 -Djava.net.preferIPv4Stack=true -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=127.0.0.1

  1. चेक जो बंदरगाहों जावा शुरू कर दिया

का उपयोग करने के लिए

tcp 0 0 0.0.0.0:37484 0.0.0.0:* LISTEN 2904/java tcp 0 0 0.0.0.0:1099 0.0.0.0:* LISTEN 2904/java tcp 0 0 0.0.0.0:45828 0.0.0.0:* LISTEN 2904/java

सभी बंदरगाहों

ssh -N -L 1099:127.0.0.1:1099 [email protected]<ec2_ip> ssh -N -L 37484:127.0.0.1:37484 [email protected]<ec2_ip> ssh -N -L 45828:127.0.0.1:45828 [email protected]<ec2_ip>

  1. कनेक्ट जावा मिशन द्वारा लिए
    1. मेक ssh सुरंगों "लोकलहोस्ट: 10 99"