所用到的资源 见附件
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]