• JBoss EAP应用获取运行模式、相关路径及节点信息


    一、背景

    某应用系统在JBoss EAP 7.0的standalone模式(单实例模式)下运行正常,但在切换到domain模式(域模式)后陆续发现一些问题。为解决这些问题产生了这样的需求:如何判断JBoss运行在哪种模式?随之又产生了其它需求:如何获取相关路径的信息?如何获取集群(Cluster)中的所有节点信息?

    二、解决思路

    对于第2个需求,是容易解决的,因为JBoss EAP预置的各种属性(property)中就包含了相关路径的定义,如:jboss.home.dir(JBoss EAP安装目录,即${JBOSS_HOME})、jboss.server.base.dir(JBoss EAP的当前Server的主目录)、jboss.domain.base.dir(JBoss EAP在域模式下的主目录)等等,详见https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/7.1/html-single/configuration_guide/的Table3.3。

    以此为基础,则第1个需求也找到一个很简单的解决方法:根据jboss.domain.base.dir的值来判断,在域模式下它的值通常是:${JBOSS_HOME}/domain,而在单实例模式下,其值为null。经测试,在7.x及6.x版都运行正常。

    但第3个需求的解决就困难的多,在查阅大量资料及反复进行试验后,终于发现可以通过wildfly-clustering-api-yyy.jar及wildfly-clustering-server-xxx.jar(其中xxx、yyy为各自的版本号)提供的接口来实现。由于wildfly-clustering-server-xxx.jar只在JBoss EAP 7.x内置加载,本解决方案只在7.x版得以验证,限于时间因素未能得出在6.x中实现的具体方法。

    三、接口类、实现类、显示页面

    重点有三个组成部分:接口类DispInfoRemote,实现类DispInfo,以及用于显示的index.jsp。

    接口类示例代码:

    package test;
    
    import java.util.List;
    
    import javax.ejb.Remote;
    
    @Remote
    public interface DispInfoRemote {
        public void setID(String sessionID);
        public void setTime(String createTime);
        public String getID();
        public String getTime();
    public List<String> getNodesInfo();
    }

    实现类示例代码:

    package test;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.annotation.Resource;
    import javax.ejb.Remote;
    import javax.ejb.Stateless;
    
    import org.wildfly.clustering.group.Group;
    import org.wildfly.clustering.group.Node;
    
    /**
     * Session Bean implementation class DispInfo
     */
    @Stateless
    @Remote
    public class DispInfo implements DispInfoRemote {
        
        @Resource(lookup = "java:jboss/clustering/group/web")  
        private Group group;
    
        //sessionID和createTime用于验证域模式下是否实现session复制
        private String sessionID;
        private String createTime;
        
        /**
         * Default constructor. 
         */
        public DispInfo() {
        }
    
        public void setID(String sessionID) {
            this.sessionID = sessionID;
        }
        public void setTime(String createTime) {
            this.createTime = createTime;
        }
        public String getID() {
            return sessionID;
        }
        public String getTime() {
            return createTime;
        }
    //获取集群中所有节点的信息
        public List<String> getNodesInfo() {
             
            List<Node> nodes = group.getNodes();
            List<String> lists = new ArrayList<String>();
     
            for (Node node: nodes)
            {
                String str = node.getName() + ", " + node.getSocketAddress();
                lists.add(str);
            }
            return lists;
        }
        
    }

    需要指出的时,集群(cluster)并非只能在域模式下模式,在单实例模式下,多个节点也可通过standalone-ha.xml或standalone-full-ha.xml组成一个集群。限于篇幅,不在本文讨论。

    index.jsp的示例代码:

    <%@ page language="java" import="java.util.*"%>
    <%@ page import="javax.naming.*, java.util.Properties" %>
    <%@ page import="test.DispInfoRemote" %>
    <%
        Hashtable<String, String> jndiProperties = new Hashtable<String, String>();
        jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
    %>
    <%!    DispInfoRemote diw = null;
    %>
    <%    try {
            Context ctx = new InitialContext(jndiProperties);
            final String appName = "";
            final String moduleName = "TestEjb";
            final String distinctName = "";
            final String beanName = "DispInfo";
            final String className = DispInfoRemote.class.getName();
        
            Object obj = ctx.lookup("ejb:" + appName + "/" + moduleName + 
                    "/" + distinctName + "/" + beanName + "!" + className);
        
            diw = (DispInfoRemote)obj;
            diw.setID(session.getId());
            out.print(session.getId());
            diw.setTime(Long.toString(session.getCreationTime()));
        } catch (NamingException e) {
            e.printStackTrace();
        }
    %>
    <html>
      <head><title>JBossEap</title></head>
      <body>
        <h1><font color="red">JBossEap</font></h1>
        <table align="centre" border="1">
          <tr>
            <td>Session ID</td>
            <td><%= this.diw.getID() %></td>
          </tr>
          <tr>
            <td>Created on</td>
            <td><%= this.diw.getTime() %></td>
          </tr>
          <tr>
            <td>"{jboss.home.dir}"</td>
            <td><%= System.getProperty("jboss.home.dir") %></td>
          </tr>
          <tr>
            <td>"{jboss.server.base.dir}"</td>
            <td><%= System.getProperty("jboss.server.base.dir") %></td>
          </tr>
          <tr>
            <td>"{jboss.domain.base.dir}"</td>
            <td><%= System.getProperty("jboss.domain.base.dir") %></td>
          </tr>
          <tr>
            <td>"{jboss.node.name}"</td>
            <td><%= System.getProperty("jboss.node.name") %></td>
          </tr>
          <tr>
            <td>"{jboss.server.name}"</td>
            <td><%= System.getProperty("jboss.server.name") %></td>
          </tr>
          <% List<String> nodesInfo = this.diw.getNodesInfo();
          %>
          <tr>
            <td>Cluster Node Count</td>
            <td><%= nodesInfo.size() %> </td>
          </tr>
          <%
             for (int i=0; i<nodesInfo.size(); i++)
             {
          %>
          <tr>
            <td>  Node <%= i+1%> </td>
            <td><%= nodesInfo.get(i) %> </td>
          </tr>
          <% }%>
        </table>
      </body>
    </html>

    四、测试结果

    此处仅仅是为测试,为图省事将上述三项放入一个工程,并打包成一个cluster.war,分别部署到JBoss EAP的单实例模式和域模式下进行测试。

    在standalone模式下的页面截图如下:

    可以看到,此时的jboss.domain.base.name的值为null,而jboss.node.name和jboss.server.name为节点的hostname,且Cluster只有一个节点,节点名等同于jboss.server.name,至于SocketAddress,缺省情况下使用standalone.xml时其值为null,而使用standalone-ha.xml或standalone-full-ha.xml时为:/IP:55200。

    在domain模式下的页面截图为:

    可以看到,此时jboss.domain.base.name的值已是${JBOSS_HOME}/domain,而jboss.node.name和jboss.server.name的值也发生改变,与在domain.xml里的配置一致;Cluster所有节点的信息也全部列出,SocketAddress也始终能获取到。

    五、总结

    通过上述方法,3个需求均得到解决,应用系统也得以修改后在域模式和集群环境下正确运行。

    吐个槽:网上能获得的JBoss EAP有效资料比较少,尤其是在不能google的情况下。其中有不少还是关于6.x版的陈旧资料,不一定适合与新的7.x版。

  • 相关阅读:
    Gothic Revival Portal
    通过CRM API for 3CXPhone与其他应用进行对接
    Asp.net Identity 2.0 作弊条
    ReportViewer作弊条
    定制与扩展Asp.NET 5 MVC内建身份验证机制
    在Dynamics CRM 2015中通过3CX插件(以及3CX windows phone)拨出电话
    在Asp.net MVC中使用Authorization Manager (AzMan)进行Windows用户身份认证
    log4net资料收集
    jQuery 插件开发文章收集
    git &github 快速入门
  • 原文地址:https://www.cnblogs.com/wggj/p/9493649.html
Copyright © 2020-2023  润新知