JNDI查找时间的巨大差异

时间:2011-08-30 09:06:00

标签: java performance weblogic weblogic-10.x

我们在Weblogic 10.3上运行的遗留J2EE Web应用程序的响应时间差异很大。该系统由两个Weblogic服务器实例(前端和后端)组成,它们运行在同一个物理服务器计算机上,另一个Oracle数据库运行在单独的主机上。每次登录系统需要超过四秒钟时,外部测量工具会提醒我们。最近这些警告频繁发生。查看处理登录请求的servlet所写的日志会显示从前端到后端的EJB调用所花费的时间。

测量时间的示例:

time    ms   
8:40:43 25
8:42:14 26
8:44:04 26
8:44:25 26
8:44:47 26
8:46:06 26
8:46:41 7744
8:47:00 27
8:47:37 27
8:49:00 26
8:49:37 26
8:50:03 8213
8:50:57 27
8:51:04 26
8:51:06 25
8:57:26 2545
8:58:13 26
9:00:06 5195

可以看出,大多数请求(70%,来自较大的样本)及时完成,但其中很大一部分需要很长时间才能完成。

在测量时间内执行的步骤如下:

  • 提供身份验证接口(前端)的会话bean的JNDI查找
  • 调用会话bean的身份验证方法(frontend-> backend)
  • 从连接池(后端)保留JDBC连接
  • 查询用户数据库(表格大小非常适中,表格应正确编入索引)(后端)
  • 读取结果集,创建POJO用户对象(后端)
  • 返回POJO用户对象(backend-> frontend)

服务器计算机上的负载非常小(99%空闲),用户数量非常适中。两个服务器上Weblogic报告的可用内存量在60%到90%之间。记录垃圾收集。主要藏品很少见,并且在发生时会在2-3秒内完成。此外,主要的GC出现似乎不会在看到长响应时间的同时发生。繁忙和非繁忙时段都会出现较长的响应时间。 JDBC连接池最大大小当前设置为80,大于并发用户数。

更新:

获得了重新启动系统的权限,并添加了更多性能日志记录。日志清楚地显示JNDI查找是花费时间的部分:

03:01:23.977 PERFORMANCE: looking up foo.bar.Bar from JNDI took 6 ms
03:14:47.179 PERFORMANCE: looking up foo.bar.Bar from JNDI took 2332 ms
03:15:55.040 PERFORMANCE: looking up foo.bar.Bar from JNDI took 1585 ms
03:29:25.548 PERFORMANCE: looking up foo.bar.Bar from JNDI took 7 ms
03:31:09.010 PERFORMANCE: looking up foo.bar.Bar from JNDI took 6 ms
03:44:25.587 PERFORMANCE: looking up foo.bar.Bar from JNDI took 6 ms
03:46:00.289 PERFORMANCE: looking up foo.bar.Bar from JNDI took 7 ms
03:59:28.028 PERFORMANCE: looking up foo.bar.Bar from JNDI took 2052 ms

查看前端和后端的GC日志显示,当发生慢速JNDI查找时,GC未完成。

创建会话时,上下文的方式如下:

Hashtable ht = new Hashtable();
ht.put(Context.PROVIDER_URL, url);
ht.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
jndiContext = new InitialContext(ht);

其中url是指向后端服务器的DNS名称和端口的t3 url。这应该没问题吧?

首先想到的是缓存从JNDI获取的引用,至少这是10年前的首选方式......但是不应该Weblogic的InitialContext实现已经执行了这个缓存,或者它是否真的取了它每次通话时后端服务器的引用?

什么可能导致频繁的慢速JNDI查找?有没有解决方法(例如缓存参考帮助)?

3 个答案:

答案 0 :(得分:6)

  

那么可能导致这种相当不稳定的行为呢?

我们说的任何话都可能是猜测。这里有一些调查问题的建议,而不是玩这个游戏:

  • 尝试使用分析器查看花费的时间。
  • 尝试使用网络工具(如WireShark)查看是否存在异常网络流量。
  • 在关键点添加一些日志记录/跟踪,以查看时间进度。
  • 查找Thread.sleep(...)来电。 (哎呀......这是猜测。)

答案 1 :(得分:2)

作为第一步,我会尝试通过记录每个步骤所花费的时间来确定执行这些步骤的哪一部分。通过这种方式,你可以消除那些无关紧要的东西并专注于正确的区域,当你想出来时,任何可能会再次发布在这里,以便人们可以给出具体的建议。

答案 2 :(得分:2)

正如StephenC所说,其中一些是猜测而没有充分的日志记录。您已清楚地列出了事务中的每个元素,但我假设您没有可以打开的logger.debug,其上有时间戳。

要看一些问题:

每个前端和后端bean在池中有多少个bean - 它应该是max-beans-in-free-pool

weblogic-ejb-jar.xml元素

如果您对后端EJB的请求多于可用的bean,那么将会有一个等待堆积。

类似地,在JDBC前端,您可以使用Weblogic控制台来监视任何争用获取连接 - 您是否在JDBC Monitoring选项卡中点击High Counts和Waits?这应该是接下来要检查的事情。