所用到的资源 见附件
log4j.properties
log4j-1.2.15.jar
slf4j-log4j12-1.5.0.jar
slf4j-api-1.5.0.jar
commons-lang-2.4.jar
一,zk内存监控要点:
Monitor接口是zk提供的zk Engine监听工具, 如果在zk.xml有该配置,zk将在桌面的创建销毁,会话的创建销毁,
以及异步更新时回调相关方法,从而可以统计会话,桌面,更新的数量等等
大致流程:实现该Monitor,的异步更新方法 -> 配置zk.xml中的monitor监听器以及log4j日志项
->添加zul视图,以及视图控制器 -> 测试
二,memory Monitor的的实现
1,Monitor的空实现,方便继承,不必关心不感兴趣的方法
package org.zkway.util.zk;
import java.util.List;
import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.Session;
import org.zkoss.zk.ui.util.Monitor;
/**
* 该类仅仅提供Monitor的空实现
*
* <p>
* Monitor类是zk提供的zk Engine监听工具, 通常用于统计会话,桌面,更新的数量
*
* @author sunflower
*
*/
abstract public class AbstractMonitor implements Monitor {
/**
* 当异步更新之后调用
* <p>
* 所谓的更新,其实可以理解为一个异步事件请求, 并不是所有的事件请求都会更新客户端视图, 只是在需要时才修改
*/
@Override
public void afterUpdate(Desktop desktop) {
}
/**
* 当异步更新之前调用
* <p>
* 所谓的更新,其实可以理解为一个异步事件请求, 并不是所有的事件请求都会更新客户端视图, 只是在需要时才修改
*/
@Override
public void beforeUpdate(Desktop desktop, List requests) {
}
/**
* 当创建新 桌面 的时候调用
*
*/
@Override
public void desktopCreated(Desktop desktop) {
}
/**
* 当桌面销毁时创建
*/
@Override
public void desktopDestroyed(Desktop desktop) {
}
/**
* 当创建新的session时调用
*/
@Override
public void sessionCreated(Session sess) {
}
/**
* 当session销毁时调用
*/
@Override
public void sessionDestroyed(Session sess) {
}
}
2,memory Monitor的的实现
package org.zkway.util.zk;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zkoss.zk.au.AuRequest;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.IdSpace;
import org.zkoss.zk.ui.sys.ExecutionCtrl;
/**
* Zkway内存变化统计
* <p>
* 仅监视客户操作的内存变化情况
*
* @author sunflower
*
*/
public class ZkwayMemoryStatistic extends AbstractMonitor {
static Logger log = LoggerFactory.getLogger(ZkwayMemoryStatistic.class);
/**
* 常量标识符,标识当前请求作用域内beforeUpdate时的内存大小
*/
private static final String REQUEST_MEMORY = "org.zkway.zk.constants.requestMemory";
@Override
public synchronized void beforeUpdate(Desktop desktop, List requests) {
ExecutionCtrl ec = (ExecutionCtrl) Executions.getCurrent();
List<AuRequest> reqs = (List<AuRequest>) requests;
long memory = Runtime.getRuntime().freeMemory();
Executions.getCurrent().setAttribute(REQUEST_MEMORY, memory);
for (AuRequest auq : reqs) {
auq.activate(); // 激活request,给AuRequest component和page属性赋值,方便下面使用
log.debug("【beforeUpdate】[{}] \tmemory [{}] kb \t{}({}) \tcmd [{}] \tPage [{}]",
new Object[] {
Executions.getCurrent().getRemoteAddr(),
memory / 1024,
auq.getComponent().getDefinition()
.getName(),
auq.getComponent().getId(),
auq.getCommand(),
getCompPath(auq.getComponent()) });
}
}
/**
* 获得组件的路径
*
* @param comp
* zk组件
* @return 组件的路径
*/
private String getCompPath(Component comp) {
StringBuilder sb = new StringBuilder();
Component current = comp;
while (current != null) {
if ((current instanceof IdSpace)
&& StringUtils.isNotBlank(current.getId())) {
sb.append(" -> ").append(current.getDefinition().getName())
.append("(").append(current.getId()).append(")");
} else {
sb.append(" -> ").append(current.getDefinition().getName());
}
current = current.getParent();
}
sb.append(" ->文件").append(comp.getPage().getRequestPath());
return sb.toString();
}
@Override
public synchronized void afterUpdate(Desktop desktop) {
ExecutionCtrl ec = (ExecutionCtrl) Executions.getCurrent();
long memory = (Long) Executions.getCurrent().getAttribute(
REQUEST_MEMORY);
long m = memory - Runtime.getRuntime().freeMemory();
memory = memory - m;
log
.debug(
"【afterUpdate 】[{}] \tmemory [{}] kb \tdecrease [{}] kb \tPage [{}] ",
new Object[] {Executions.getCurrent().getRemoteAddr(), memory / 1024, m / 1024,
ec.getCurrentPage().getRequestPath() });
}
}
二,配置zk.xml,添加monitor监听器
<!-- Optional -->
<!-- the following listener is used to see # of sessions, desktops... --> <listener> <description>[Optional] Mointor the statistic</description> <listener-class> org.zkway.util.zk.ZkwayMemoryStatistic</listener-class> </listener>
三,添加视图页面,控制器,测试
<window id="indexWin" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:n="http://www.zkoss.org/2005/zk/native" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:w="http://www.zkoss.org/2005/zk/client" xmlns:ca="http://www.zkoss.org/2005/zk/client/attribute" apply="org.zkway.ctrl.IndexController"> <!-- borderlayout如果有父节点,那么必须设置height属性,否则不显示 --> <borderlayout height="1800px"> <!-- 北(上) --> <north height="100px" style="background-image:url(images/bg.png);"> <div> <button forward="onTestMemory" id="btnTestMemory" label="test memory" /> </div> </north>
import java.util.HashMap;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.util.GenericComposer;
public class IndexController extends GenericComposer {
private static final long serialVersionUID = -3801962286418473844L;
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
}
public void onTestMemory() {
for (int i = 0; i < 1000; i++)
new HashMap(100);
}
}
监控记录
【beforeUpdate】[127.0.0.1] memory [7105] kb button(btnTestMemory) cmd [onClick] Page [ -> button -> div -> north -> borderlayout -> window(indexWin) ->文件//WEB-INF/content/index.zul]
【afterUpdate 】[127.0.0.1] memory [7098] kb decrease [7] kb Page [//WEB-INF/content/index.zul]
【beforeUpdate】[127.0.0.1] memory [7052] kb button(btnTestMemory) cmd [onClick] Page [ -> button -> div -> window(welcomeWin) ->文件/WEB-INF/content/welcome.zul]
【afterUpdate 】[127.0.0.1] memory [7045] kb decrease [6] kb Page [/WEB-INF/content/welcome.zul]
【beforeUpdate】[127.0.0.1] memory [7006] kb button(btnTestMemory) cmd [onClick] Page [ -> button -> div -> north -> borderlayout -> window(indexWin) ->文件//WEB-INF/content/index.zul]
【afterUpdate 】[127.0.0.1] memory [6999] kb decrease [6] kb Page [//WEB-INF/content/index.zul]
【beforeUpdate】[127.0.0.1] memory [6953] kb button(btnTestMemory) cmd [onClick] Page [ -> button -> div -> window(welcomeWin) ->文件/WEB-INF/content/welcome.zul]
【afterUpdate 】[127.0.0.1] memory [6946] kb decrease [7] kb Page [/WEB-INF/content/welcome.zul]
【beforeUpdate】[127.0.0.1] memory [8579] kb button(btnTestMemory) cmd [onClick] Page [ -> button -> div -> north -> borderlayout -> window(indexWin) ->文件//WEB-INF/content/index.zul]
【afterUpdate 】[127.0.0.1] memory [8568] kb decrease [10] kb Page [//WEB-INF/content/index.zul]
【beforeUpdate】[127.0.0.1] memory [8525] kb button(btnTestMemory) cmd [onClick] Page [ -> button -> div -> window(welcomeWin) ->文件/WEB-INF/content/welcome.zul]
【afterUpdate 】[127.0.0.1] memory [8520] kb decrease [5] kb Page [/WEB-INF/content/welcome.zul]
【beforeUpdate】[127.0.0.1] memory [8477] kb button(btnTestMemory) cmd [onClick] Page [ -> button -> div -> north -> borderlayout -> window(indexWin) ->文件//WEB-INF/content/index.zul]
【afterUpdate 】[127.0.0.1] memory [8471] kb decrease [6] kb Page [//WEB-INF/content/index.zul]
【beforeUpdate】[127.0.0.1] memory [8428] kb button(btnTestMemory) cmd [onClick] Page [ -> button -> div -> window(welcomeWin) ->文件/WEB-INF/content/welcome.zul]
【afterUpdate 】[127.0.0.1] memory [8422] kb decrease [5] kb Page [/WEB-INF/content/welcome.zul]