在%JBOSS_HOME%/bin/run.sh文件中将
JAVA_OPTS="$JAVA_OPTS -Dprogram.name=$PROGNAME "
修改为:
JAVA_OPTS="$JAVA_OPTS -Dprogram.name=$PROGNAME -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
#-Djava.rmi.server.hostname=192.168.2.2 #this must be added for Tomacat6
//for Tomcat ... find #Execut The Requested Command in catalina.sh file.
可以在Jconsole里实现远程监控了:
远程进程 192.168.10.31:8950
或 service:jmx:rmi:///jndi/rmi://192.168.10.31:8950/jmxrmi
注意:9999表示监控的端口号,确保指定的端口不被占用;可以采用netstat -an来查看已经占用的端口;配合lsof -i:portnum来查看占用端口的具体应用程序;另外如果开启了防火墙服务,请确保端口能够透过防火墙访问;
./run.sh -b192.168.1.5,必须通过-b参数指定Jboss服务器绑定的地址;(不是必须的。。。看每台Server的配置而言)
add Jar:
jbossall-client.jar
public MBeanServerConnection getRemoteMBConn(){
try{
MBeanServerConnection mbs=null;
Registry registry=LocateRegistry.getRegistry(ip, Integer.parseInt(port));
RMIServer stub=null;
JMXConnector jmxc=null;
if (stub == null) {
stub = (RMIServer) registry.lookup("jmxrmi");
}
jmxc = new RMIConnector(stub, null);
jmxc.connect();
mbs=jmxc.getMBeanServerConnection();
return mbs;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Main:
RemoteMonitor re = new RemoteMonitor("192.168.2.2","9898");
MBeanServerConnection rm = re.getRemoteMBConn();
ObjectName name;
name = new ObjectName("jboss.ws:service=ServiceEndpointManager");
System.out.println("jboss主机 ip = " + re.getIp());
System.out.println("主机 名字 = " + rm.getAttribute(name, "WebServiceHost"));
System.out.println("HTTP 端口 = " + rm.getAttribute(name, "WebServicePort"));
System.out.println("Monitor 端口 = " + re.getLinkPort());
name = new ObjectName("java.lang:type=Threading");
System.out.println("总共线程数 = " + rm.getAttribute(name, "TotalStartedThreadCount"));
System.out.println("活动线程数 = " + rm.getAttribute(name, "ThreadCount"));
System.out.println("守护线程数 = " + rm.getAttribute(name, "DaemonThreadCount"));
//------------------------ JVM -------------------------
//堆使用率
ObjectName heapObjName = new ObjectName("java.lang:type=Memory");
MemoryUsage heapMemoryUsage = MemoryUsage.from((CompositeDataSupport) rm.getAttribute(heapObjName, "HeapMemoryUsage"));
long maxMemory = heapMemoryUsage.getMax();//堆最大
long commitMemory = heapMemoryUsage.getCommitted();//堆当前分配
long usedMemory = heapMemoryUsage.getUsed();
System.out.println("堆最大值:" + maxMemory);
System.out.println("已分配堆:" + commitMemory);
System.out.println("已使用堆:" + usedMemory);
System.out.println("堆使用率:" + (double) usedMemory / commitMemory * 100 + "%");//堆使用率
System.out.println();
MemoryUsage nonheapMemoryUsage = MemoryUsage.from((CompositeDataSupport) rm.getAttribute(heapObjName, "NonHeapMemoryUsage"));
long nonmaxMemory = nonheapMemoryUsage.getMax();
long noncommitMemory = nonheapMemoryUsage.getCommitted();
long nonusedMemory = nonheapMemoryUsage.getUsed();
System.out.println("非堆最大值:" + nonmaxMemory);
System.out.println("已分配非堆:" + noncommitMemory);
System.out.println("已使用非堆:" + nonusedMemory);
System.out.println("非堆使用率:" + (double) nonusedMemory / noncommitMemory * 100 + "%");
System.out.println();
ObjectName permObjName = new ObjectName("java.lang:type=MemoryPool,name=PS Perm Gen");
if (permObjName != null) { //只有HotSpot才有
MemoryUsage permGenUsage = MemoryUsage.from((CompositeDataSupport) rm.getAttribute(permObjName, "Usage"));
long max = permGenUsage.getMax();
long committed = permGenUsage.getCommitted();
long used = permGenUsage.getUsed();
System.out.println("持久代最大值:" + max);
System.out.println("已分配持久代:" + committed);
System.out.println("已使用持久代:" + used);
System.out.println("持久代 堆使用率:" + (double) used / committed * 100 + "%");
System.out.println();
}
ObjectName oldObjName = new ObjectName("java.lang:type=MemoryPool,name=PS Old Gen");
MemoryUsage oldGenUsage = MemoryUsage.from((CompositeDataSupport) rm.getAttribute(oldObjName, "Usage"));
long max1 = oldGenUsage.getMax();
long committed1 = oldGenUsage.getCommitted();
long used1 = oldGenUsage.getUsed();//
System.out.println("老年代最大值:" + max1);
System.out.println("已分配老年代:" + committed1);
System.out.println("已使用老年代:" + used1);
System.out.println("老年代 堆使用率:" + (double) used1 / committed1 * 100 + "%");
System.out.println();
ObjectName EdenObjName = new ObjectName("java.lang:type=MemoryPool,name=PS Eden Space");
MemoryUsage EdenGenUsage = MemoryUsage.from((CompositeDataSupport) rm.getAttribute(EdenObjName, "Usage"));
long max2 = EdenGenUsage.getMax();
long committed2 = EdenGenUsage.getCommitted();
long used2 = EdenGenUsage.getUsed();//
System.out.println("新生代Eden区 最大值:" + max2);
System.out.println("已分配新生代Eden区:" + committed2);
System.out.println("已使用新生代Eden区:" + used2);//Byte
System.out.println("新生代Eden区 堆使用率:" + (double) used2 / committed2 * 100 + "%");
System.out.println();
ObjectName SurvivorObjName = new ObjectName("java.lang:type=MemoryPool,name=PS Survivor Space");
MemoryUsage SurvivorGenUsage = MemoryUsage.from((CompositeDataSupport) rm.getAttribute(SurvivorObjName, "Usage"));
long max3 = SurvivorGenUsage.getMax();
long committed3 = SurvivorGenUsage.getCommitted();
long used3 = SurvivorGenUsage.getUsed();//
System.out.println("新生代Survivor区 最大值:" + max3);
System.out.println("已分配新生代Survivor区:" + committed3);
System.out.println("已使用新生代Survivor区:" + used3);//Byte
System.out.println("新生代Survivor区 堆使用率:" + (double) used3 / committed3 * 100 + "%");
System.out.println();
1. 修改上文中的catalina脚本中的JAVA_OPT参数,将
-Dcom.sun.management.jmxremote.authenticate="false" 修改为:
-Dcom.sun.management.jmxremote.authenticate="true"
2. 将$JRE/lib/management/jmxremote.password.template文件在同目录下复制一份,重命名为$JRE/lib /management/jmxremote.password,编辑jmxremote.password,添加允许访问的用户名及密码,比如添加用户 zxwh,密码为zxme,则在文件尾添加一行:
zxwh zxme
注意用户密码不能包含空格,tab等字符
3. 编辑$JRE_HOME/lib/management/jmxremote.access文件,对刚才添加的用户赋予一定的权限:
zxwh readonly (或者readwrite)
4. 确认jmxremote.password和jmxremote.access两个文件中的用户是相同的。注意如果jmxremote.access中没有对应用户的话,配置是无效的。
注:以上配置文件的位置都是可以更改的,具体配置方法在此不再赘述。
5. 由于jmxremote.password中的密码都是明文保存的,所以jmxremote.password、jmxremote.access文件的权限要注意,应该设置为只有owner才可读,当然这个用户也必须是启动tomcat的用户。
6. 启动jconsole进行连接,在用户名和口令处输入设定的用户和密码。
7. 使用密码认证方式进行连接,不但可以提高安全性,而且可以对用户的权限进行设置。如果不使用密码认证的方式,则无法对用户的权限进行限制。
apache:
httpd.conf
ExtendedStatus On
<location /server-status>
SetHandler server-status
Order Allow,Deny
Allow from all
</location>
http://192.168.2.8/server-status
monitor tomcat another way :
in tomcat-users.xml
<role rolename="manager-gui"/> <user username=“manager" password=“1234" roles="manager-gui"/>
then use shell to get status from tomcat...
#!/bin/sh
#$1:port; $2:user; $3:psword; $4:infoParam;
#stty -echo
STATUS_ADDR="http://localhost:$1/manager/status?XML=true"
USER="$2"
PASS="$3"
# sample rate, default: 5seconds
SAMPLE_RATE=5
# if press "Ctrl+c", stop monitor
EXIT_SIGNAL=2
# connector to monitor
CONNECTOR="http-$1"
# result directory to store data
RESULT_DIR="/tmp"
# perf data file
PERF_DATA="perf_data"
# jvm data file
JVM_DATA="jvm_data"
# connector data file
CONNECTOR_DATA="connector_data"
# thread data file
THREAD_DATA="thread_data"
# request data file
REQUEST_DATA="request_data"
# ===========================Output Error Message========================
# Show Error Message and exit, get one parameter
errorMsg()
{
if [[ $# -eq 1 ]]; then
echo "Runtime Error: $1"
exit 1
else
echo "Function Error: $1"
exit 127
fi
}
if [ $# lt 4 ]; then
echo "Miss Args"
exit 1
fi
#####freejvm totaljvm maxjvm maxthreads currentthread busythread maxtime processingtime requestcount errorcount bytesreceived bytessent
wget --http-user="$USER" --http-password="$PASS" "$STATUS_ADDR" -O "$PERF_DATA" || errorMsg "Failed to get data, please check the connection"
case $4 in
freejvm )
sed 's/.*<jvm>//g;s/<\/jvm>.*//g' $PERF_DATA | awk -F \' '{print $2}'
;;
totaljvm )
sed 's/.*<jvm>//g;s/<\/jvm>.*//g' $PERF_DATA | awk -F \' '{print $2}'
;;
maxjvm )
sed 's/.*<jvm>//g;s/<\/jvm>.*//g' $PERF_DATA | awk -F \' '{print $2}'
;;
maxthreads )
sed 's/.*'$CONNECTOR'.>//g;s/<\/connector>.*//g' $PERF_DATA >> $CONNECTOR_DATA
sed 's/.*<threadInfo//g;s/\/>.*//g' $CONNECTOR_DATA | awk -F \" 'NR<2{print $2}'
;;
currentthread )
sed 's/.*'$CONNECTOR'.>//g;s/<\/connector>.*//g' $PERF_DATA >> $CONNECTOR_DATA
sed 's/.*<threadInfo//g;s/\/>.*//g' $CONNECTOR_DATA | awk -F \" 'NR==2{print $4}'
;;
busythread )
sed 's/.*'$CONNECTOR'.>//g;s/<\/connector>.*//g' $PERF_DATA >> $CONNECTOR_DATA
sed 's/.*<threadInfo//g;s/\/>.*//g' $CONNECTOR_DATA | awk -F \" 'NR==2{print $6}'
;;
maxtime )
sed 's/.*'$CONNECTOR'.>//g;s/<\/connector>.*//g' $PERF_DATA >> $CONNECTOR_DATA
sed 's/.*<requestInfo//g;s/\/>.*//g' $CONNECTOR_DATA | awk -F \" 'NR<2{print $2}'
;;
processingtime )
sed 's/.*'$CONNECTOR'.>//g;s/<\/connector>.*//g' $PERF_DATA >> $CONNECTOR_DATA
sed 's/.*<requestInfo//g;s/\/>.*//g' $CONNECTOR_DATA | awk -F \" 'NR==2{print $4}'
;;
requestcount )
sed 's/.*'$CONNECTOR'.>//g;s/<\/connector>.*//g' $PERF_DATA >> $CONNECTOR_DATA
sed 's/.*<requestInfo//g;s/\/>.*//g' $CONNECTOR_DATA | awk -F \" 'NR==2{print $6}'
;;
errorcount )
sed 's/.*'$CONNECTOR'.>//g;s/<\/connector>.*//g' $PERF_DATA >> $CONNECTOR_DATA
sed 's/.*<requestInfo//g;s/\/>.*//g' $CONNECTOR_DATA | awk -F \" 'NR==2{print $8}'
;;
bytesreceived )
sed 's/.*'$CONNECTOR'.>//g;s/<\/connector>.*//g' $PERF_DATA >> $CONNECTOR_DATA
sed 's/.*<requestInfo//g;s/\/>.*//g' $CONNECTOR_DATA | awk -F \" 'NR==2{print $10}'
;;
bytessent )
sed 's/.*'$CONNECTOR'.>//g;s/<\/connector>.*//g' $PERF_DATA >> $CONNECTOR_DATA
sed 's/.*<requestInfo//g;s/\/>.*//g' $CONNECTOR_DATA | awk -F \" 'NR==2{print $12}'
;;
esac