热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

JNDI查找时间的巨大差异-HugevarianceinJNDIlookuptimes

WereexperiencinghugevarianceinresponsetimesonalegacyJ2EEwebapplicationrunningonWeblo

We're experiencing huge variance in response times on a legacy J2EE web application running on Weblogic 10.3. The system consists of two Weblogic server instances (frontend and backend) which run on the same physical server machine and an Oracle database running on a separate host. External measurement tool alerts us every time a login to the system takes more than four seconds. Lately these warnings have been frequent. Looking at the log written by the servlet handling the login requests reveals that the time is spent on an EJB call from the frontend to the backend.

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

Example of the measured times:

测量时间的示例:

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

As can be seen, most of the requests (70%, taken from a larger sample) complete in timely fashion but a significant portion of them take a very long time to complete.

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

The steps performed during the measured time are the following:

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

  • JNDI lookup of the session bean offering the authentication interface (frontend)
  • 提供身份验证接口(前端)的会话bean的JNDI查找

  • Calling the authentication method of the session bean (frontend->backend)
  • 调用会话bean的身份验证方法(frontend-> backend)

  • Reserving a JDBC connection from the connection pool (backend)
  • 从连接池(后端)保留JDBC连接

  • Making a query to the user database (table size is very moderate and the table should be properly indexed) (backend)
  • 对用户数据库进行查询(表大小非常适中,表应该正确编入索引)(后端)

  • Reading the result set, creating the POJO user object (backend)
  • 读取结果集,创建POJO用户对象(后端)

  • Returning the POJO user object (backend->frontend)
  • 返回POJO用户对象(后端 - >前端)

The load on the server machine is very small (99% idle) and the number of users is very moderate. Amount of free memory reported by Weblogic varies between 60% and 90% on both servers. Garbage collection is logged. Major collections are rare and complete in 2-3 seconds when they do occur. Further, the major GC occurances seem not to happen at the same time when long response times are seen. Long response times occur on both busy and non-busy hours. The JDBC connection pool max size is currently set to 80 which is more than the number of concurrent users.

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

Update:

Got a permission to reboot the system with some more performance logging added. The log clearly shows that the JNDI lookup is the part where the time is spent:

获得了重新启动系统的权限,并添加了更多性能日志记录。日志清楚地显示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

Looking at the GC logs of the frontend and backend shows that GC is not done when the slow JNDI lookups occur.

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

The context is got the following way when a session is created:

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

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

where url is a t3 url pointing to the DNS name and port of the backend server. This should be ok, right?

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

First thing to pop into mind is to cache the references got from JNDI, at least this was the preferred way to go 10 years ago... But shouldn't Weblogic's InitialContext implementation already do this caching, or does it really fetch the reference from the backend server on each call?

要记住的第一件事是缓存从JNDI获得的引用,至少这是10年前的首选方式......但是不应该Weblogic的InitialContext实现已经执行了这个缓存,或者它是否真的从中获取引用每次通话后端服务器?

What could be causing the frequent slow JNDI lookups? Is there a workaround for this (e.g. would caching the references help)?

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

3 个解决方案

#1


6  

So what could be causing this rather erratic behavior?

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

Anything we say is likely to be a guess. Rather than playing that game, here are some suggestions for investigating the problem:

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

  • Try using a profiler to see where the time is being spent.
  • 尝试使用分析器查看花费的时间。

  • Try using a network tool (like WireShark) to see if there is anomalous network traffic.
  • 尝试使用网络工具(如WireShark)查看是否存在异常网络流量。

  • Add some logging / tracing at key points to see where the time is going.
  • 在关键点添加一些日志记录/跟踪以查看时间的去向。

  • Look for Thread.sleep(...) calls. (Ooops ... that's a guess.)
  • 寻找Thread.sleep(...)调用。 (哎呀...这是猜测。)

#2


2  

As a first step, I would to try and isolate which part of those steps performed caused the problem by logging the amount of time each of them take. That way you can eliminate things that are irrelevant and focus on the right area, any may be post here again when you figure that out so that people can give specific advice.

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

#3


2  

As StephenC says, some of this is guesswork without adequate logging statements in between. You have clearly listed each element in the transaction, but I assume you don't have a logger.debug which you can switch on which has timestamps on it.

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

Some questions to look at:

要看的一些问题:

How many beans in pool for each of the front end and backend beans - it should be the max-beans-in-free-pool element of the weblogic-ejb-jar.xml

每个前端和后端bean在池中有多少个bean - 它应该是weblogic-ejb-jar.xml中的max-beans-in-free-pool元素

If you have more requests to the backend EJB than beans available, then there will be a waiting pileup.

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

Similarly on the JDBC front, you can use the Weblogic console to monitor any contention with getting connections - are you hitting High Counts and Waits in the JDBC Monitoring tab? That should be the next thing to check.

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


推荐阅读
author-avatar
手机用户2502915433
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有