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版。
轉載于:https://www.cnblogs.com/wggj/p/9493649.html
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的JBoss EAP应用获取运行模式、相关路径及节点信息的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 江西国联是国有吗
- 下一篇: Python直接赋值,浅拷贝和深度拷贝