时间监控--Profiler使用方法
一、 概述
Profiler是一个时间统计程序,他通过在程序中埋点,将埋点时间记录入线程变量中以实现革离,最后dump出结果,得出埋点时间树。
二、 Profiler常用方法(Profiler类的静态方法)
1、Start
当前线程埋点计时的开始,标识当前埋点的开始时间,每个埋点产生一个Entry,被压入线程变量中的栈中,当start方法被调用时,就是一个时间点栈的开始, 如果start方法被重复调用,则覆盖前面被放入线程变量的栈,每个线程只允许一个栈的存在。该方法的参数标识该Entry信息。
2、 Enter
向线程变量中的栈压入当前埋点信息Profiler.entry("..."),标识当前埋点的开始时间,如果此线程此前未调用start方法,则此方法调用不执行任何操作。
3、Release
结束栈里当前Entry时间,打上结束时间标识。
4、GetDuration
获取耗费的总时间,是从start到当前的中时间,如果start的Entry没有被release,则getDuration的结果为-1,所以只有栈的最底层的Entry被release后getDuration得到的数值才有意义。
5、Dump
当线程内的所有Entry被release后,通过dump的到整个线程内埋点的时间树,列出所有Entry,并统计各自所占用的时间。
Profiler是一个时间统计程序,他通过在程序中埋点,将埋点时间记录入线程变量中以实现革离,最后dump出结果,得出埋点时间树。
二、 Profiler常用方法(Profiler类的静态方法)
1、Start
当前线程埋点计时的开始,标识当前埋点的开始时间,每个埋点产生一个Entry,被压入线程变量中的栈中,当start方法被调用时,就是一个时间点栈的开始, 如果start方法被重复调用,则覆盖前面被放入线程变量的栈,每个线程只允许一个栈的存在。该方法的参数标识该Entry信息。
2、 Enter
向线程变量中的栈压入当前埋点信息Profiler.entry("..."),标识当前埋点的开始时间,如果此线程此前未调用start方法,则此方法调用不执行任何操作。
3、Release
结束栈里当前Entry时间,打上结束时间标识。
4、GetDuration
获取耗费的总时间,是从start到当前的中时间,如果start的Entry没有被release,则getDuration的结果为-1,所以只有栈的最底层的Entry被release后getDuration得到的数值才有意义。
5、Dump
当线程内的所有Entry被release后,通过dump的到整个线程内埋点的时间树,列出所有Entry,并统计各自所占用的时间。
6、Reset
清除当前线程内的计数器栈。当一次调用完成后,在dump出时间树后应该将其清除,并须再次调用start方可重新计时。
清除当前线程内的计数器栈。当一次调用完成后,在dump出时间树后应该将其清除,并须再次调用start方可重新计时。
三、 Profiler埋点方式
在消息中心项目中主要采用两种埋点方式,一种是业务程序中直接埋入Profiler代码,另一种是利用Spring方法拦截器,将Profiler代码埋入拦截器中。两种方法各有优劣,所以在项目中两种方式综合应用,相互补充。
1、直接埋点
优点是在业务代码中埋点可以设置任意粒度,能够显示程序中微小范围内的时间变化。
缺点是Profiler耦合进了业务代码,埋点分布于业务程序的各处,不便于阅读和修改,同时由于其要带try{}finally{}块,将业务代码分割的支离破碎,造成业务代码的断层。
用例如下:
在消息中心项目中主要采用两种埋点方式,一种是业务程序中直接埋入Profiler代码,另一种是利用Spring方法拦截器,将Profiler代码埋入拦截器中。两种方法各有优劣,所以在项目中两种方式综合应用,相互补充。
1、直接埋点
优点是在业务代码中埋点可以设置任意粒度,能够显示程序中微小范围内的时间变化。
缺点是Profiler耦合进了业务代码,埋点分布于业务程序的各处,不便于阅读和修改,同时由于其要带try{}finally{}块,将业务代码分割的支离破碎,造成业务代码的断层。
用例如下:
- public void sendWithChannels(final MessageTaskDO messageTask,
- final MessageTypeDO messageType,final UserInfoDO userInfo,
- final int chs) throws MessageException{
- int channelInt = chs;
- UserInfoFuture userInfoFuture = null;
- Profiler.start("TagTask isFinish");
- try{
- if (messageTask.getTaskPreStatus() == MessageTaskDO.FALURE_NOTSEND_RETRY
- && messageStatusDAO.isFinish(messageTask.getTaskID(), userInfo.getTargetID())){
- return;
- }
- Profiler.enter("Task Filter");
- try{
- channelInt = getChannelsAfterFilter(messageType, userInfo, channelInt);
- }finally{
- Profiler.release();
- }
- Profiler.enter("Task Fill UserInfo");
- try{
- channelInt = getChannelsAfterUInfoFilled(userInfo, userInfoFuture, channelInt);
- }finally{
- Profiler.release();
- }
- List<Channel> channels = null;
- Map<Channel, Integer> channelTemplateId = null;
- Map<String, String> mapContext =