时间监控--Profiler使用方法

本文介绍了Profiler用于时间监控的方法,包括直接埋点和Spring拦截器埋点,并分析了各自的优缺点。在使用Profiler时,需要注意方法对的匹配以避免内存泄露,以及在多线程环境下正确获取耗时。文中还展示了Profiler生成的耗时详细树形结构,揭示了调用服务的耗时分布。
摘要由CSDN通过智能技术生成

时间监控--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,并统计各自所占用的时间。
  6、Reset
清除当前线程内的计数器栈。当一次调用完成后,在dump出时间树后应该将其清除,并须再次调用start方可重新计时。
三、 Profiler埋点方式
在消息中心项目中主要采用两种埋点方式,一种是业务程序中直接埋入Profiler代码,另一种是利用Spring方法拦截器,将Profiler代码埋入拦截器中。两种方法各有优劣,所以在项目中两种方式综合应用,相互补充。
  1、直接埋点
优点是在业务代码中埋点可以设置任意粒度,能够显示程序中微小范围内的时间变化。
缺点是Profiler耦合进了业务代码,埋点分布于业务程序的各处,不便于阅读和修改,同时由于其要带try{}finally{}块,将业务代码分割的支离破碎,造成业务代码的断层。
用例如下:
  1. public void sendWithChannels(final MessageTaskDO messageTask,    
  2.             final MessageTypeDO messageType,final UserInfoDO userInfo,   
  3.             final int chs) throws MessageException{   
  4.         int channelInt = chs;   
  5.         UserInfoFuture userInfoFuture = null;         
  6.         Profiler.start("TagTask isFinish");   
  7.         try{   
  8.             if (messageTask.getTaskPreStatus() == MessageTaskDO.FALURE_NOTSEND_RETRY   
  9.                     && messageStatusDAO.isFinish(messageTask.getTaskID(), userInfo.getTargetID())){   
  10.                 return;   
  11.             }   
  12.             Profiler.enter("Task Filter");   
  13.             try{   
  14.                 channelInt = getChannelsAfterFilter(messageType, userInfo, channelInt);   
  15.             }finally{   
  16.                 Profiler.release();   
  17.             }   
  18.             Profiler.enter("Task Fill UserInfo");   
  19.             try{   
  20.                 channelInt = getChannelsAfterUInfoFilled(userInfo, userInfoFuture, channelInt);   
  21.             }finally{   
  22.                 Profiler.release();   
  23.             }   
  24.             List<Channel> channels = null;   
  25.             Map<Channel, Integer> channelTemplateId = null;   
  26.             Map<String, String> mapContext = 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值