前段时间做了个项目,主要优化一个产品页面。整个优化过程中,针对velocity的分析过程占了比较大的比重,这里做一下整理和记录。
velocity版本:
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.6.4</version>
</dependency>
通过velocimacro.library.autoreload=false进行关闭autoreload,因为使用了同步锁,非常影响性能
"TP-Processor20" daemon prio=10 tid=0x00002aab4c7cb800 nid=0x3d46 waiting for monitor entry [0x00000000423a3000]
java.lang.Thread.State: BLOCKED (on object monitor)
at org.apache.velocity.runtime.VelocimacroFactory.getVelocimacro(VelocimacroFactory.java:571)
- waiting to lock <0x00002aaad964ca48> (a org.apache.velocity.runtime.VelocimacroFactory)
at org.apache.velocity.runtime.RuntimeInstance.getVelocimacro(RuntimeInstance.java:1563)
at org.apache.velocity.runtime.directive.RuntimeMacro.render(RuntimeMacro.java:199)
at org.apache.velocity.runtime.parser.node.ASTDirective.render(ASTDirective.java:175)
at org.apache.velocity.runtime.parser.node.ASTBlock.render(ASTBlock.java:72)
at org.apache.velocity.runtime.parser.node.ASTIfStatement.render(ASTIfStatement.java:87)
at org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:336)
at org.apache.velocity.Template.merge(Template.java:328)
at org.apache.velocity.Template.merge(Template.java:235)
说明:
1. velocity针对macros的自动reload,采用了同步排他锁进行控制
2. 在velocity实现中,org.apache.velocity.runtime.VelocimacroFactory.getVelocimacro中,line 569,每次获取一个宏对象,都会进行一个是否需要自动reload的逻辑控制
3. 针对设置了autoReloadLibrary为true时,velocity就会先获取一个同步锁,然后进行相应检查判断是否需要重新载入
默认是关闭的,因为公司开发的框架中针对线上和线下velocity参数设置有所不同,在开发环境开启了autoreload,所以导致在测试时发现block现象很严重。
优化2: veocity cache策略
velocity针对template查找有一定的cache策略,比如是否启用cache,cache的数量大小。resource.manager.defaultcache.size=89(默认值为89,0代表不限制)
TP-Processor12" daemon prio=10 tid=0x00002aab4c868800 nid=0x3d3c waiting on condition [0x0000000042abf000]
java.lang.Thread.State: RUNNABLE
at org.springframework.core.io.ClassPathResource.getFile(ClassPathResource.java:175)
at org.springframework.core.io.AbstractResource.exists(AbstractResource.java:51)
at com.alibaba.citrus.service.velocity.impl.AbstractResourceLoader.getLastModified(AbstractResourceLoader.java:72)
at org.apache.velocity.runtime.VelocimacroFactory.getVelocimacro(VelocimacroFactory.java:601)
- locked <0x00002aaad964ca48> (a org.apache.velocity.runtime.VelocimacroFactory)
at org.apache.velocity.runtime.RuntimeInstance.getVelocimacro(RuntimeInstance.java:1563)
at org.apache.velocity.runtime.directive.RuntimeMacro.render(RuntimeMacro.java:199)
at org.apache.velocity.runtime.parser.node.ASTDirective.render(ASTDirective.java:175)
at org.apache.velocity.runtime.parser.node.ASTBlock.render(ASTBlock.java:72)
at org.apache.velocity.runtime.parser.node.ASTIfStatement.render(ASTIfStatement.java:87)
at org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:336)
at org.apache.velocity.Template.merge(Template.java:328)
at org.apache.velocity.Template.merge(Template.java:235)
1. velocity中使用ResourceManager进行资源查找,在ResourceManagerImpl资源管理查找中,定义了一份resource globalCache
2. 在globalCache.initialize()方法中,会读取定义 resource.manager.defaultcache.size配置,默认值只有89
3. global cache生效,必须要开启对应xxx.resource.loader.cache=true,这样的size调整才有意义,不然velocity个根本不会进行global cache
优化3:modificationCheckInterval优化
如果开启了优化2,则会对该Resource定期进行是否已经进行了修改的扫梨型身材怎么穿衣描,file.resource.loader.modificationCheckInterval = 2 (单位为秒,如果不需要hot deploy,可以设置更大点)
说明:
1. velocity通过ResourceManagerImpl进行资源加载,在开启优化2后,会针对从cache中返回的resource资源(velocity中模板都认为是一个resource)。赛尔号有什么自杀精灵
2. 针对resource会进行requiresChecking()判断,主要的依据就是modificationCheckInterval。 0代表永不做检查处理
背景知识