2014-05-08 11 views
11

सक्षम मैं JMX निगरानी के साथ एक जावा अनुप्रयोग इस सक्षम कर दिया है:अनुमति दें JMX निगरानी के साथ पुन: प्रारंभ जावा अनुप्रयोग तुरंत

-Dcom.sun.management.jmxremote.port=9999 \ 
// some other properties omitted 

लेकिन जब मैं अनुप्रयोग फिर से आरंभ करने का प्रयास करें, कुछ समय मैं एक त्रुटि JMX पोर्ट नंबर का कहना है मिल गया यह पहले से ही उपयोग में है। यह स्वीकार्य नहीं है।

तो मैं इस त्रुटि से बचने के लिए अंतर्निहित सॉकेट के लिए SO_REUSEADDR को सत्य पर सेट करना चाहता हूं लेकिन कोई संबंधित जेएमएक्स गुण नहीं मिला।

कोई विचार?

+0

क्या आपने देखा है कि उस पोर्ट का उपयोग किस एप्लिकेशन का उपयोग कर रहा है? – BevynQ

+0

मुझे अपना आवेदन होना चाहिए। जब मैं एप्लिकेशन को रोकता हूं, तो मुझे लगता है कि इस बंदरगाह से जुड़ी सॉकेट वास्तव में बंद करने के लिए 2MSL के लिए TIME_WAIT स्थिति पर जाती है। तो मैं इस बंदरगाह को पुन: प्रयोज्य बनाना चाहता हूं। – George

+0

SO_REUSEADDR इस तरह से काम नहीं करता है। यह सॉकेट को विशिष्ट आईपी पते सुनने और दूसरों को अनदेखा करने की अनुमति देता है। या तो एक ही आवेदन दो बार चल रहा है या इस बंदरगाह को पकड़ने वाला एक और एप्लीकेशन है। – BevynQ

उत्तर

6

मुझे डर है कि आप कमांड लाइन से ऐसा नहीं कर सकते हैं।

आप एक RMIServerSocketFactory, जो इच्छित विकल्प (SO_REUSEADDR) के साथ ServerSockets का उत्पादन बनाने की आवश्यकता होगी। यहाँ

डॉक्स: http://docs.oracle.com/javase/8/docs/technotes/guides/rmi/socketfactory/

किसी और एक ही समस्या को सुलझाने: https://svn.apache.org/viewvc?view=revision&revision=r1596579

+0

धन्यवाद। मुझे डर है कि वास्तव में एकमात्र समाधान हो सकता है। यह सब एक साथ रखकर यह उम्मीद की तुलना में यह अधिक verbose है, लेकिन फिर भी कुछ भी बेहतर नहीं है। – Boris

-1

आपके आवेदन कि JMX मार देगा पर बंद हुक जोड़ें।

// kill process with port 9999  
fuser -k 9999/tcp 
+0

यह मंच-निर्भर होगा (जो मेरे मामले में ठीक होगा) लेकिन अधिक महत्वपूर्ण बात यह काम नहीं करती है। Fuser के माध्यम से प्रक्रिया को मारना SO_REUSEADDR के संबंध में व्यवहार को बदलना प्रतीत नहीं होता है। मैंने एक साधारण वर्ग के साथ कोशिश की और अभी भी BindException मिला – Boris

1

हां, आपको जेएमएक्स कनेक्टर प्रोग्रामेटिक रूप से बनाना चाहिए। आसान कामकाज के रूप में, आप रनटाइम में जेएमएक्स के लिए एक और बंदरगाह का चयन कर सकते हैं यदि डिफ़ॉल्ट बंदरगाह केवल मारे गए प्रक्रिया से व्यस्त है। या जब तक यह सफल न हो जाए तब तक अपने पोर्ट को बार-बार खोलने का प्रयास करें।

यहां कोड स्निपेट है जिसका उपयोग मैं जेकोनसोल-संगत जेएमएक्स कनेक्टर खोलने के लिए करता हूं। स्कैला में, क्षमा करें, लेकिन आपको इसे आसानी से अनुकूलित करने में सक्षम होना चाहिए

def startJmx(port: Int): Unit = { 
if (port < 1) { 
    return 
} 

val log = LoggerFactory.getLogger(getClass) 

log.info("Starting JMX server connector on port {}", port) 

val registry = LocateRegistry.createRegistry(port) 

val server = ManagementFactory.getPlatformMBeanServer() 

val url = new JMXServiceURL(s"service:jmx:rmi:///jndi/rmi://localhost:$port/jmxrmi") 

val connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, Collections.emptyMap(), server) 

val thread = new Thread { 
    override def run = try { 
    connectorServer.start() 
    } catch { 
    case e: Exception => log.error("Unable to start JMX connector", e) 
    } 
} 
thread.setDaemon(true) 
thread.setName("JMX connector Thread") 
thread.start() 
} 
0

मुझे एक ही समस्या थी। यह मेरे आवेदन का पहला उदाहरण था (जिसे मैंने रोक दिया था) जो अभी भी इस बंदरगाह की सदस्यता ले चुका था, इसलिए नया उदाहरण शुरू नहीं हो सका। मेरे मामले में इसे सॉकेट TIME_WAIT तंत्र के साथ नहीं करना था, बल्कि इस तथ्य के साथ कि stop() पर कॉल करने के बाद, इसमें कुछ समय लगेगा जब तक कि सभी चलने वाले धागे सुन्दर तरीके से समाप्त न हों। मेरे मामले में जो काम किया गया था, वह एप्लिकेशन को रोकने से पहले बीन अधिकार को अनधिकृत कर रहा था ताकि सॉकेट मुक्त हो।

private void unregisterBeanForName(String name) { 
     try { 

      JMXServiceURL jmxServiceURL = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://127.0.0.1:9999/jmxrmi"); 
      JMXConnector cc = JMXConnectorFactory.connect(jmxServiceURL); 
      MBeanServerConnection mbsc = cc.getMBeanServerConnection(); 
//This information is available in jconsole 
      ObjectName serviceConfigName = new ObjectName("YourObjectName"); 
      mbsc.unregisterMBean(serviceConfigName); 
// Close JMX connector 
      cc.close(); 
     } catch (Exception e) { 
      System.out.println("Exception occurred: " + e.toString()); 
      e.printStackTrace(); 
     } 
    } 
0

यह एक वैकल्पिक हल हो सकता है: दूरस्थ सर्वर पर आप दो बंदरगाहों हो सकता है: 9999 और 9998 आपका आवेदन वैकल्पिक एक बूलियन हर बार पुन: प्रारंभ 9999 से कनेक्ट करने का फैसला करने के 9999

के पास भेज या 99 8 9।

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