通过weblogic API解析如何获取weblogic中服务的IP和端口操作

 更新时间:2021年06月19日 14:36:25   作者:一步一台阶  
这篇文章主要介绍了通过weblogic API解析如何获取weblogic中服务的IP和端口操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

我们的服务是部署在weblogic上的,最近遇到一个需求,需要在代码中获取weblogic部署当前服务的IP地址和端口。

后来搜到一段代码,亲测有效:

public static String getIpAndPort(){
    try {
        InitialContext initialContext = new InitialContext();
		MBeanServer tMBeanServer;
		MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
			tMBeanServer = (MBeanServer) initialContext.lookup("java:comp/env/jmx/runtime");	
		ObjectName tObjectName = new ObjectName(
				"com.bea:Name=RuntimeService,Type=weblogic.management.mbeanservers.runtime.RuntimeServiceMBean");
		ObjectName serverrt = (ObjectName) tMBeanServer.getAttribute(tObjectName, "ServerRuntime");
		String port = String.valueOf(tMBeanServer.getAttribute(serverrt, "ListenPort"));
		String listenAddr = (String) tMBeanServer.getAttribute(serverrt, "ListenAddress");
		String[] tempAddr = listenAddr.split("/");
		if (tempAddr.length == 1) {
			listenAddr = tempAddr[0];
		} else if (tempAddr[tempAddr.length - 1].trim().length() != 0) {
			listenAddr = tempAddr[tempAddr.length - 1];
		} else if (tempAddr.length > 2) {
			listenAddr = tempAddr[tempAddr.length - 2];
		}
		StringBuilder sBuilder = new StringBuilder(listenAddr);
		sBuilder.append(":");
		sBuilder.append(port);
		System.out.print(sBuilder);
		return sBuilder.toString();
		} catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedObjectNameException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstanceNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (AttributeNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ReflectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MBeanException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}	

可要理解这段代码后面的原理和思路,真是费劲了,需要了解以下知识:

JMX

JNDI

RMI

EJB

总结成一句话就是,通过web应用通过weblogic提供的JNDI访问weblogic的JMX中的对象。JNDI后台用的技术就是EJB,而EJB是RMI在java语言上的实现。上述几个概念的具体含义,读者可以自行查询,网上资料很多。

下面回归正题,先从思路上详细分析下标题中的内容如何实现。

作为服务端代码,最后都是生成一个war放到服务器上去运行的。那从代码本身的程序来说,是肯定无法知道自己会被放到什么类型的web容器中、自己可以被访问的IP地址和端口号的。那谁知道的呢?只有web容器知道。换句话说,从这次要解决的问题上看,只有weblogic自己知道在其内部部署的应用被放到了哪个IP下,端口是多少。也就是说,解决这个问题的关键是,我们的服务程序如何去“问”weblogic容器,自己的IP和端口是多少。

好的,我们继续来想这个问题。能不能从weblogic容器中获取到服务的IP和端口号,取决于weblogic愿不愿意把这些信息开放给你,换句话说,取决于weblogic是否对外开放了可以获取其内部服务IP和端口的通道。

目前来看,必然是提供了的,查了weblogic的官网,发现了这样一段说明:

文章的链接地址为(oracle的官方文档):

https://docs.oracle.com/cd/E13222_01/wls/docs81/jmx/overview.html

只要获取到weblogic的MBeanServer,然后从MBeanServer中取出对应的ObjectName的属性,就可以获取到IP和端口了。这里面提到了JMX和RMI的概念,不清楚的,可以从上文找博文链接查看。

有一点是比较好理解的,就是weblogic必定会把自己处在runtime的服务信息写入到MBeanServer,然后我们通过MBeanServer把这些信息拿出来就行了。至于为什么要有MBeanServer,又是和JMX相关,这里就不再赘述。现在的关键问题是,我们的本地程序,如何访问到weblogic的MBeanServer?答案是通过InitialContext的lookup函数,而lookup函数最终的访问方式是JNDI。也就是说,我们最终是通过weblogic对外提供的JNDI访问到weblogic的MBeanServer的。MBeanServer在两个程序(weblogic和服务程序)之间的传递是通过EJB的。

拿到weblogic的MBeanServer之后,如何获取程序的IP的端口呢?这个当然要看weblogic是怎么设置进去的。按照设置进去的规则取出来就可以了。那如何知道weblogic的设置规则呢?我们继续看weblogic的文档。

原文链接:

https://docs.oracle.com/cd/E13222_01/wls/docs90/jmx/understandWLS.html

发现了什么问题,红框中的文字,不就是刚才样例代码中的文字吗?再来看下面这段代码,通过本地程序访问Runtime MBean Server

If the classes for the JMX client are located in a J2EE module, such as an EJB or Web application, then the JNDI name for the Runtime MBeanServer is:

java:comp/env/jmx/runtime

翻译下,如果JMX客户端(EJB或者Web程序)在J2EE本地,那么通过JNDI访问Runtime MBean Server的名称为java:comp/env/jmx/runtime。

Runtime MBean Server是MBeanServer的一种,通过下面的说明可以看到:

所以可以把Runtime MBean Server赋值给MBeanServer.

好,下一步,我们继续来调查,从Runtime MBean Server中如何取到端口和IP。通过以下代码获取RuntimeServerMBean的ServerRuntime属性。

        ObjectName tObjectName = new ObjectName(
                "com.bea:Name=RuntimeService,Type=weblogic.management.mbeanservers.runtime.RuntimeServiceMBean");
        ObjectName serverrt = (ObjectName) tMBeanServer.getAttribute(tObjectName, "ServerRuntime");

点开ServerRuntime属性,看看它还有什么二级属性,果然:

ListenPort和ListenAddress就是ServerRuntime的二级属性。通过以下代码获取到:

		String port = String.valueOf(tMBeanServer.getAttribute(serverrt, "ListenPort"));
		String listenAddr = (String) tMBeanServer.getAttribute(serverrt, "ListenAddress");

至此,所有代码解析完毕。

但是仔细想想,这段代码其实是有瑕疵的。换句话说,健壮性还不够。如果我们用的web容器不是weblogic怎么办?那代码岂不是就不管用了。所以我建议,完善下这段代码,增加对web容器的判断。其他web容器中如果获取IP和端口,还请读者自己探索。先通过下面的函数判断下当前的web容器:

public static String getServerName() {
		String serverName = null;
		if (ServerDetector.isWebLogic()) {
			serverName = "WebLogic";
		} else if (ServerDetector.isTomcat()) {
			serverName = "Tomcat";
		} else if (ServerDetector.isWebSphere()) {
			serverName = "WebSphere";
		} else if (ServerDetector.isSupportsComet()) {
			serverName = "SupportsComet";
		} else if (ServerDetector.isResin()) {
			serverName = "Resin";
		} else if (ServerDetector.isOC4J()) {
			serverName = "OC4J";
		} else if (ServerDetector.isJOnAS()) {
			serverName = "JOnAS";
		} else if (ServerDetector.isJetty()) {
			serverName = "Jetty";
		} else if (ServerDetector.isJBoss()) {
			serverName = "JBoss";
		} else if (ServerDetector.isGeronimo()) {
			serverName = "Geronimo";
		} else if (ServerDetector.isGlassfish()) {
			serverName = "Glassfish";
		} else if (ServerDetector.isGlassfish2()) {
			serverName = "Glassfish2";
		} else if (ServerDetector.isGlassfish3()) {
			serverName = "Glassfish3";
		}
		return serverName;
	}
 

ServerDetector需要对应jar包,利用maven引入的配置为:

<dependency>
		    <groupId>com.liferay.portal</groupId>
		    <artifactId>portal-kernel</artifactId>
		    <version>5.2.3</version>
		    <scope>provided</scope>
 
</dependency>

遇到问题,一定要多探索,与其看别人的博文,不如自己深入研究API,找样例代码。用一手资料。以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java数据结构和算法学习之汉诺塔示例

    java数据结构和算法学习之汉诺塔示例

    这篇文章主要介绍了java数据结构和算法中的汉诺塔示例,需要的朋友可以参考下
    2014-02-02
  • IDEA中maven无法下载源码的解决方法

    IDEA中maven无法下载源码的解决方法

    这篇文章主要为大家详细介绍了当IDEA中maven无法下载源码时改如何解决,文中通过图文为大家进行了详细讲解,需要的小伙伴可以参考一下
    2023-08-08
  • Spring开发核心之AOP的实现与切入点持久化

    Spring开发核心之AOP的实现与切入点持久化

    面向对象编程是一种编程方式,此编程方式的落地需要使用“类”和 “对象”来实现,所以,面向对象编程其实就是对 “类”和“对象” 的使用,面向切面编程,简单的说,就是动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程
    2022-10-10
  • Java中父类Object的常用方法总结

    Java中父类Object的常用方法总结

    这篇文章给大家介绍了Java中父类Object的三个常用方法,对大家学习或使用Java具有一定的参考借鉴价值,有需要的朋友们下面来一起看看吧。
    2016-09-09
  • Java由浅入深通关抽象类与接口下

    Java由浅入深通关抽象类与接口下

    在类中没有包含足够的信息来描绘一个具体的对象,这样的类称为抽象类,接口是Java中最重要的概念之一,它可以被理解为一种特殊的类,不同的是接口的成员没有执行体,是由全局常量和公共的抽象方法所组成,本文给大家介绍Java抽象类和接口,感兴趣的朋友一起看看吧
    2022-04-04
  • Java annotation元注解原理实例解析

    Java annotation元注解原理实例解析

    这篇文章主要介绍了Java annotation元注解原理实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Idea Jrebel 报错:Cannot reactivate,offline seat in use

    Idea Jrebel 报错:Cannot reactivate,offline 

    本文主要介绍了Idea Jrebel 报错:Cannot reactivate,offline seat in use,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • java实现四子棋游戏

    java实现四子棋游戏

    这篇文章主要为大家详细介绍了java实现四子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-03-03
  • Spring Data MongoDB 数据库批量操作的方法

    Spring Data MongoDB 数据库批量操作的方法

    在项目开发中经常会批量插入数据和更新数据的操作,这篇文章主要介绍了Spring Data MongoDB 数据库批量操作的方法,非常具有实用价值,需要的朋友可以参考下
    2018-11-11
  • 例题详解Java dfs与记忆化搜索和分治递归算法的使用

    例题详解Java dfs与记忆化搜索和分治递归算法的使用

    递归指函数调用自身。常用的递归算法有dfs(深度优先搜索)、记忆化搜索和分治,接下来将用几个算法题来带你熟练掌握它
    2022-04-04

最新评论