我使用的重要技术有:Glassfish v3,JSF 2.0,JPA 2.0,EclipseLink 2.0.2,log4j 1.2.16,commons-logging 1.1.1。
我的问题是应用程序的某些部分非常慢。我用 netbeans 6.8 Profiling 功能对此进行了分析。
予。记录 - 我使用log4j和apache commons记录来在日志记录文件和控制台中生成日志。日志也出现在glassfish的服务器日志中。我使用记录器如下:
private static Log logger = LogFactory.getLog(X.class);
...
if (logger.isDebugEnabled()) {
...
logger.debug("Log...");
}
问题在于,有时这样的短语需要花费很多时间(大约800毫秒)。当我切换到java.util.logging时,它不是那么糟糕但也很慢(200毫秒乐队)。有什么问题? 我需要一些日志记录... 更新 - 从Netbeans 6.8切换到Netbeans 6.9.1后,解决了慢速日志问题。 - 当日志打印到其控制台时,Netbeans 6.8可能非常慢?!所以它与Log4J或公共记录无关。
II。数据库操作: 我第一次调用以下EJB的find方法需要2,4 s!其他呼叫仅持续几毫秒。那么为什么第一次手术需要很长时间?这是(仅仅因为)连接建立还是与依赖注入有关 XFacade以及这些注射何时进行?:
@Stateless
@PermitAll
public class XFacade {
@PersistenceContext(unitName = "de.x.persistenceUnit")
private EntityManager em;
// Other DI's
...
public List<News> find(int maxResults) {
return em.createQuery(
"SELECT n FROM News n ORDER BY n.published DESC").setMaxResults(maxResults).getResultList()
}
}
III。依赖注入,JNDI查找:DI之间是否存在差异( @EJB ...)和关注性能的InitialContext查找?注入本地,远程和无接口EJB之间是否存在差异(性能视图)?
IV。 Managed Beans - 我使用了许多Session Scoped Beans,因为ViewScope似乎非常错误,而Request Scoped实际上并不总是如此。还有其他选择吗? - 因为这些Beans并不慢,但服务器端内存在整个会话期间都会受到压力。当用户退出时需要一些时间!
诉EJB - 我不使用MDB会话Bean和Singleton Bean。他们经常使用 @EJB 注释注入其他Bean。一个Singleton Bean使用 @Schedule 注释来重复操作。我发现一个有趣的事情是,从EJB 3.1开始,您可以使用 @Asynchronous Annotation来使Session Bean Method异步。在实现有关性能的EJB时,我通常应该考虑什么?
也许有人可以给我一些提高javaee应用程序性能的一般和/或具体技巧,特别是关于上述问题。谢谢!
答案 0 :(得分:4)
首先,您应该使用负载测试工具在真实环境中对应用程序进行测试,您无法从IDE中观察到的行为中得出有效的结论。最重要的是,不要忘记分析实际上会改变表演。
予。记录(...)从Netbeans 6.8切换到Netbeans 6.9.1后解决了慢速记录的问题
这是您无法信任IDE内部行为的第一个证据。
II。数据库操作:我第一次调用以下EJB的find方法需要2,4秒!其他呼叫仅持续几毫秒。那么为什么第一次操作需要很长时间?
可能是因为某些GlassFish服务被(延迟)加载,可能是因为必须实例化无状态会话bean(SLSB),可能是因为必须创建EntityManagerFactory
。分析说了什么?为什么在激活应用服务器日志时会看到什么?什么问题,因为后续的电话没问题?
III。依赖注入,JNDI查找:DI之间是否存在差异(@EJB ...)和关注性能的InitialContext查找?
JNDI查找很昂贵,事实上在好的旧服务定位器中使用一些缓存。因此,我不认为使用DI时性能最差(我实际上希望容器能够擅长)。老实说,这对我来说从来都不是一个问题。
当您进行性能优化时,典型的工作流程是:1)检测慢速操作2)找到瓶颈2)对其进行操作3)如果操作仍然不够快,请返回2)。根据我的经验,瓶颈是DAL中90%的时间。如果您的瓶颈是DI,则IMO没有性能问题。换句话说,我认为你太担心而且你非常接近“过早优化”。
IV。托管豆 - 我使用了许多Session Scoped Beans,因为ViewScope似乎非常错误,而Request Scoped实际上并不总是如此。还有其他选择吗? - 因为这些Beans并不慢,但服务器端内存在整个会话期间都会受到压力。当用户退出时需要一些时间!
我没有看到任何问题:)所以我没有什么可说的。 更新(回复评论):使用会话范围可能确实更便宜。但一如既往地衡量。
诉EJB - 我不使用MDB会话Bean和Singleton Bean。他们经常使用@EJB Annotation注入其他Bean。一个Singleton Bean使用@Schedule Annotations开始重复操作。我发现一个有趣的事情是,从EJB 3.1开始,您可以使用@Asynchronous Annotation使Session Bean Method异步。在实现有关性能的EJB时,我通常应该考虑什么?
SLSB(和MDB)的表现非常好。但是在使用SLSB时,请注意以下几点:
Local
over Remote
接口。我还建议不要使用某些东西,除非你真的需要这个功能并且有一个真正的问题需要解决(例如@Asynchronous)。
也许有人可以给我一些提高javaee应用程序性能的一般和/或具体技巧,特别是关于上述问题。谢谢!
专注于您的数据访问代码,我很确定这代表了大多数业务流程执行时间的80%。
正如我已经暗示的那样,你确定你确实遇到了性能问题吗?我不相信。但如果你真的是,那就测量IDE之外的性能。
答案 1 :(得分:1)
我同意Pascal Thivent的观点,认为“过早优化”是不好的。很好地设计你的代码,然后担心性能。
此外,您可以针对性能或内存保护进行优化。选择哪一个导致你在早上头痛,并优化。
我其实非常喜欢NetBeans的分析器;它是最好的免费之一,恕我直言。
我建议:
de.x
)或排除Java核心类。这样您的应用程序就不会陷入分析并且会给您带来误导性的数字。基本上,尽量让“开销”尽可能低,如底部的栏所示。
浏览您的网络应用程序一段时间,查看占用大部分CPU时间的内容。还要注意一些对象是延迟加载的,所以第一次访问代码时可能会很慢。此外,您正在使用JIT编译器,因此代码在运行它的第一个(或第二个......)时间可能会很慢,但随着您更频繁地使用该代码,它会变得更快。简而言之,请使用Web应用程序一段时间。您可以使用Selenium“记录”网络会话并“回放”它。这样您就可以获得更好的性能指标,并查看应用程序的运行速度,而不是测量“预热时间”。
如果有一段特定的代码或类导致您遇到麻烦,请使用profiling points查看导致该段代码变慢的原因。
如果您有一段特定的代码导致您出现问题,请随时发布。