Liferay的性能一直都让大家关注,运行他的demo,也许每个版本都会给人一点惊喜,包括后台的一些变化,也许你看到他的速度似乎是变快了,而我觉得从4.4开始,速度并没有太大的变化(表现形式强了不少),但是还是可以接受的。而我们更需要关注的应该是稳定性方面的问题,因为在发布到生产环境的时候性能经常会不可思议的大幅下降。更糟糕的是,应用程序平时运行正常,老板或者重要客户或碰上大规模操作应用的时候却反应缓慢,甚至出错down掉。详细的日志记录和分析对于追踪这些间歇性的性能瓶颈尤为重要。所以在这里介绍用Perf4j去完成liferay来进行性能分析和监控工作。也许你会说用Jprofiler或Jprobe,或者用LR来对程序进行监控和测试,但是这些工具总是耗时而且当你只想监控某个方法的时候,这些工具是显得如此的笨重,特别在生产环境下,通过网络,很难对其进行监控。所以选择了Perf4J对日常的操作进行监控。
在Liferay中配置Perf4J并不困难,配合Log4J来使用,为了使用异步的Appender,所以Log4j的配置用xml文件。
步骤如下:
1)添加所需的jar包到/WEB-INF/lib中
2)配置log4j.xml
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}:%L] %m%n" />
</layout>
</appender>
<!-- Perf4J appenders -->
<!--
This AsyncCoalescingStatisticsAppender groups StopWatch log messages
into GroupedTimingStatistics messages which it sends on the
downstream appenders defined below
-->
<appender name="CoalescingStatistics"
class="org.perf4j.log4j.AsyncCoalescingStatisticsAppender">
<!--
The TimeSlice option is used to determine the time window for which
all received StopWatch logs are aggregated to create a single
GroupedTimingStatistics log. Here we set it to 10 seconds, overriding
the default of 30000 ms
-->
<param name="TimeSlice" value="10000"/>
<appender-ref ref="fileAppender"/>
<!--
Note how the GraphingStatisticsAppenders have been attached to the
CoalescingStatistics here.
-->
<appender-ref ref="graphExecutionTimes"/>
<appender-ref ref="graphExecutionTPS"/>
</appender>
<!-- This file appender is used to output aggregated performance statistics -->
<appender name="fileAppender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.base}/logs/liferay/perfStats.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m%n"/>
</layout>
</appender>
<!--
This first GraphingStatisticsAppender graphs Mean execution times for the
firstBlock and secondBlock tags
-->
<appender name="graphExecutionTimes"
class="org.perf4j.log4j.GraphingStatisticsAppender">
<!-- Possible GraphTypes are Mean, Min, Max, StdDev, Count and TPS -->
<param name="GraphType" value="Mean"/>
<appender-ref ref="graphsFileAppender"/>
</appender>
<!--
This second GraphingStatisticsAppender graphs transactions per second
for the firstBlock and secondBlock tags
-->
<appender name="graphExecutionTPS"
class="org.perf4j.log4j.GraphingStatisticsAppender">
<param name="GraphType" value="TPS"/>
<appender-ref ref="graphsFileAppender"/>
</appender>
<!--
This file appender is used to output the graph URLs generated
by the GraphingStatisticsAppenders
-->
<appender name="graphsFileAppender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.base}/logs/liferay/perfGraphs.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m%n"/>
</layout>
</appender>
<logger name="org.perf4j.TimingLogger" additivity="false">
<level value="INFO"/>
<appender-ref ref="CoalescingStatistics"/>
</logger>
3)如果要在运行中查看监控图片,则需要在web.xml中添加
<servlet>
<servlet- name>perf4j</servlet- name>
<servlet- class>org.perf4j.log4j.servlet.GraphingServlet</servlet-class>
<init-param>
<param- name>graphNames</param-name>
<param- value>graphExecutionTimes,graphExecutionTPS</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet- name>perf4j</servlet- name>
<url- pattern>/perf4j</url- pattern>
</servlet- mapping>
4)Liferay中调用perf4j,三种方式:
①编码方式,侵入性强,但是可以在任何地方调用,我觉得liferay的编码有点乱,而且很多写在页面上,所以这种方式挺适合liferay的
StopWatch stopWatch = new Slf4JStopWatch();
……
……
……
stopWatch.stop("loginCheck");
②Annotation方式
配置
<aop:aspectj-autoproxy/>
<!--
Declare the TimingAspect that we want to weave into the other beans
defined in this config file.
-->
<bean id="timingAspect" class="org.perf4j.log4j.aop.TimingAspect"/>
注:在liferay的主程序中,定义bean timingAspect,你会发现tomcat启动的时候会在读取bean之后停住不往下进行,没花太多的时间去找原因,有兴趣的朋友可以看看是不是有这个情况并找找原因和大家分享。而这个配置在liferay插件形式开发的插件上定义,完全运行良好。
@Profiled(tag = "getCompanies")
public List getCompanies() throws SystemException {
return companyPersistence.findAll();
}
应用条件
* Any objects to be woven must exist as Spring-managed beans declared in the Spring container. This is necessary because, in order to wrap object instances with the required proxies, the Spring container needs to control the lifecycle of your objects.
* Any method being @Profiled MUST be a public method.
* If you have a method on your spring bean that calls another @Profiled method directly, then that method will NOT be timed as you will not be going through the Spring proxy to make the call. Note this is NOT the case when using AspectJ directly. The Spring documentation explains the effect proxies have on AOP-enabled methods.
③Aop拦截器方式,当你想对某一些类每个方法进行监控的时候,上面两个方式显然工作量很大,所以写个拦截器(完全是懒人的做法,一般不会每个方法都监控,测试时候也许会这样玩玩)
spring定义
<bean id="perf4jInterceptor" class="com.liferay.portal.interceptor.Perf4jInterceptor"/>
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*Finder.impl</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>perf4jInterceptor</value>
</list>
</property>
</bean>
拦截器编写(tag名为"className_methodName")
public class Perf4jInterceptor implements MethodBeforeAdvice, AfterReturningAdvice {
private Map<String, StopWatch> watches = new HashMap<String, StopWatch>();
public void before(Method method, Object[] args, Object target) throws Throwable {
String completeMethodName = getCompleteMethodName(target, method);
// 创建性能日志记录器
StopWatch stopWatch;
if (watches.containsKey(completeMethodName)) {
stopWatch = watches.get(completeMethodName);
stopWatch.start();
} else {
stopWatch = new Slf4JStopWatch(completeMethodName, Arrays.toString(args));
watches.put(completeMethodName, stopWatch);
}
}
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
String completeMethodName = getCompleteMethodName(target, method);
// 记录性能
if (watches.containsKey(completeMethodName)) {
StopWatch stopWatch = watches.get(completeMethodName);
stopWatch.stop();
}
}
/**
* 根据目标对象与方法获取方法完整名称.
* @param target 目标对象
* @param method 方法
* @return 方法完整名称
*/
private String getCompleteMethodName(Object target, Method method) {
String className = "";
if (target != null) {
className = target.toString();
int loc = className.indexOf("@");
if (loc >= 0) {
className = className.substring(className.lastIndexOf(".") + 1, loc);
}
}
return className + "_" + method.getName();
}
}
监控结果:
Log文件:
图形界面:
有兴趣的朋友不妨配置试试,但工具只能给我们分析问题时候带来方便和可能,而真正重要的还是分析这些数据的能力,然后才能具备解决问题的能力。有兴趣的朋友也来和大家分享一下经验吧!
分享到:
相关推荐
Perf4J是一款轻量级的Java性能度量和监控工具,主要设计用于提供应用程序的性能剖析和计时。这个工具允许开发者轻松地在代码中插入性能计时器,然后收集和报告这些计时器的数据,帮助优化和理解程序运行时的性能瓶颈...
- 如果你想自动地对方法进行计时,Perf4J 提供了 `@Profiled` 注解,可以与面向切面编程(AOP)框架如 AspectJ 或 Spring AOP 结合使用。这样,你可以将性能监控应用到特定的方法上,而无需手动创建和管理 `...
这可能是项目中的一个示例类,展示了如何在业务代码中使用Perf4j进行性能度量。通常,我们会使用Perf4j的StopWatch类或@StopWatch注解来标记需要度量的方法。例如,在UserService中,我们可能对关键操作如用户查询...
首先,perf的核心功能包括事件采样、硬件事件统计、软件事件监控、性能计数器管理和分析报告生成。通过事件采样,perf可以收集运行时的性能数据,如CPU周期、缓存未命中、分支预测错误等,并根据这些信息定位程序的...
Google Perftools 的主要功能是通过采样方式对程序中的 CPU 使用情况进行“画像”,从而对程序中各个函数的调用关系和耗时情况进行分析。这种方式可以帮助开发者快速地找到程序中最耗时的部分,从而对其进行优化,以...
perf 是 Linux 中的一个性能分析工具,能够对应用程序的性能进行详细的分析。perf 由 Linux 社区维护,Intel 也为其贡献了代码。perf 的主要特点是抽象硬件,支持软件事件,可以在多种架构上运行。 perf 的架构...
本压缩包包含了`perf`工具本身以及相关的自动化运行脚本和库文件,便于用户进行性能测试和分析。 `perf`主要功能包括: 1. **采样(Sampling)**:`perf record`命令可以周期性地暂停程序,记录当前指令位置,通过...
perf annotate 命令用于对性能分析数据进行注释和解释。 ### perf data perf data 命令用于显示性能分析数据。 ### perf diff perf diff 命令用于比较两个性能分析结果的差异。 ### perf evlist perf evlist ...
perf4j-0.9.16-log4jonly.jar
这些机制使perf能够对应用程序和内核的性能进行深入分析。 在硬件层面,了解cache、流水线、超标量、乱序执行和分支预测等概念对于性能优化至关重要。Cache的存在是为了弥补处理器和内存之间速度差异,提高数据访问...
在开始性能分析前,我们需要进行前期准备,包括登录到 WebSphere 控制台,选择服务器,进入性能监控基础结构(PMI)页面,启用性能监控基础结构(PMI),选择定制监控级别,启用动态高速缓存、JDBC 连接池、JVM 运行...
Perf 的工作原理依赖于硬件中的性能监控单元(Performance Monitoring Unit, PMC),这是一个可以检测特定条件下的性能事件及其发生次数的CPU组件。在软件层面,perf 内置于内核,分散在各个功能模块中,负责统计与...
通过运行`sudo echo 0 >/proc/sys/kernel/kptr_restrict`和`sudo echo -1 >/proc/sys/kernel/perf_event_paranoid`,我们可以临时开启这些功能,允许perf工具访问内核地址和进行性能监控。 接下来,我们使用perf...
perf-tooling, 性能分析监视和优化工具列表 性能工具 欢迎使用高性能工具。性能工具是一个共享资源,用来跟踪新的和现有的性能工具。捐赠添加新工具你想添加一个工具? Great !创建一个问题,我们将把它添加到 perf...
4. **事件定制**:perf支持自定义事件,用户可以根据需要定义特定的性能事件进行监控,增强了分析的灵活性和针对性。 5. **内存分析**:perf还可以分析内存使用情况,如页面缓存、分配和释放的内存块等,帮助我们...
- **ZeroMQ REQ-REP模型测试**:使用perf进行On-CPU和Off-CPU火焰图的生成,分析ZeroMQ通信模型的性能。 - **nginx HTTP分析**:配置和启动nginx服务器,利用HTTP压测工具wrk进行压力测试,生成On-CPU和Off-CPU...
perf主要用于性能瓶颈的查找和热点代码的定位,通过对处理器相关性能指标和操作系统相关性能指标进行剖析,帮助开发者优化程序对硬件资源的使用效率,从而提升程序性能。 perf的基本工作原理是通过性能事件...
Linux Perf是一款功能强大且广泛使用的性能分析工具,能够追踪和记录内核事件、采集系统性能数据,并提供了多种强大的分析和展示方式。然而,Linux Perf的使用需要一定的专业知识和经验,且其展示方式不够直观,难以...
本文将详细介绍perf的基本使用方法和核心命令,帮助读者掌握这一强大的性能分析利器。 首先,perf的安装并不复杂,只要确保Linux系统的内核版本在2.6.31以上。通常,可以通过yum源或者源码方式进行安装。源码安装时...