存档

‘Weblogic’ 分类的存档

Weblogci10中关于managed、admin server之间Http连接超时的问题

2009年8月30日 admin 没有评论

客户提了这么个问题:admin server因为out of memory导致性能很差,此时managed server连接admin server的话,可能因为网络原因或者admin server因为OOM而导致的低性能,最终导致managed server很多线程挂死在socket read上。如果没有超时机制,这样的线程会一直挂着,如果这样的线程很多的话,系统线程资源逐渐会被消耗完,从而引起managed server无法提供响应。下面是这个客户的线程堆栈,

Thread-90 “[STUCK] ExecuteThread: ‘6′ for queue: ‘weblogic.kernel.Default (self-tuning)’” <alive, in native, suspended, priority=1, DAEMON> {
jrockit.net.SocketNativeIO.readBytesPinned(SocketNativeIO.java:???)
jrockit.net.SocketNativeIO.socketRead(SocketNativeIO.java:25)
java.net.SocketInputStream.socketRead0(SocketInputStream.java:???)
java.net.SocketInputStream.read(SocketInputStream.java:107)
java.io.BufferedInputStream.fill(BufferedInputStream.java:189)
java.io.BufferedInputStream.read(BufferedInputStream.java:234)
^– Holding  lock: java.io.BufferedInputStream@5cc3faf[thin lock]
weblogic.net.http.MessageHeader.isHTTP(MessageHeader.java:214)
weblogic.net.http.MessageHeader.parseHeader(MessageHeader.java:141)
weblogic.net.http.HttpClient.parseHTTP(HttpClient.java:477)
^– Holding lock: java.io.BufferedInputStream@5cc3faf[thin lock]
weblogic.net.http.HttpURLConnection.getInputStream(HttpURLConnection.java:329)
^– Holding lock: java.io.BufferedInputStream@5cc3faf[thin lock]
weblogic.rjvm.http.HTTPClientJVMConnection.connect(HTTPClientJVMConnection.java:161)
^– Holding lock: java.io.BufferedInputStream@5cc3faf[thin lock]
weblogic.rjvm.http.HTTPClientJVMConnection.createConnection(HTTPClientJVMConnection.java:86)
weblogic.rjvm.ConnectionManager.createConnection(ConnectionManager.java:1723)
weblogic.rjvm.ConnectionManager.findOrCreateConnection(ConnectionManager.java:1330)
^– Holding lock: java.io.BufferedInputStream@5cc3faf[thin lock]
^– Holding lock: weblogic.net.http.HttpClient@5cc3ea0[thin lock]
weblogic.rjvm.ConnectionManager.bootstrap(ConnectionManager.java:440)
weblogic.rjvm.ConnectionManager.bootstrap(ConnectionManager.java:315)
weblogic.rjvm.RJVMManager.findOrCreateRemoteInternal(RJVMManager.java:220)
^– Holding lock: java.io.BufferedInputStream@5cc3faf[thin lock]
weblogic.rjvm.RJVMManager.findOrCreate(RJVMManager.java:206)
weblogic.rjvm.RJVMFinder.findOrCreateRemoteServer(RJVMFinder.java:226)
weblogic.rjvm.RJVMFinder.findOrCreate(RJVMFinder.java:170)
^– Holding lock: java.io.BufferedInputStream@5cc3faf[thin lock]
weblogic.rjvm.ServerURL.findOrCreateRJVM(ServerURL.java:154)
weblogic.jndi.WLInitialContextFactoryDelegate.getInitialReference(WLInitialContextFactoryDelegate.java:384)
weblogic.jndi.Environment.getInitialReference(Environment.java:223)
weblogic.server.channels.RemoteChannelServiceImpl.registerInternal(RemoteChannelServiceImpl.java:153)
^– Holding lock: java.io.BufferedInputStream@5cc3faf[thin lock]
weblogic.server.channels.RemoteChannelServiceImpl.access$300(RemoteChannelServiceImpl.java:46)
weblogic.server.channels.RemoteChannelServiceImpl$TimerListenerImpl.timerExpired(RemoteChannelServiceImpl.java:101)
weblogic.timers.internal.TimerImpl.run(TimerImpl.java:253)
weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:464)
weblogic.work.ExecuteThread.execute(ExecuteThread.java:197)
weblogic.work.ExecuteThread.run(ExecuteThread.java:164)

现在的问题是,对于这种问题可不可以通过超时设定来释放线程。weblogic中, RJVM(即server之间,可能是admin-to-managed,也可能是managed-to-managed)之间,连接的协议有两类五种, 两类是http、t3,五种是http、https、t3、t3s、local。超时设定时协议层面的东西,所以我们这里只讨论http和t3。

对于t3,从上面的trace可以看到,连接的创建从ServerURL.findOrCreateRJVM()开始,这个方法有多种实现,不同的实现使 用不同的timeout,客户端程序可以通过向environment中set一个叫做weblogic.jndi.requestTimeout的变 量,如果不做设定,则使用系统默认的DEFAULT_CONNECTION_TIMEOUT,这是个静态值(0)。而在上面的stack trace中,我们可以看到,environment是在RemoteChannelServiceImpl中定义的,这个environment对于客 户而言是不可配置的,而weblogic自己的这个env中是不设定request timeotu的,也就是,无论哪种方式,connectionTimeout/readTimeout对于t3,都是不可配置的,而且默认是没有超时 的。

而对于http,HTTPClientJVMConnection在创建HttpURLConnection的时候,会读取系统环境变量中的如下两个变量,
weblogic.http.client.defaultReadTimeout
weblogic.http.client.defaultConnectTimeout
如果没有设定,这两个变量的默认值均为-1,即不做timeout。如果我们作了设定,这两个值即读超时、连接超时都会生效。这两个值可以用于解决上述的问题。

Popularity: unranked [?]

weblogic92连接池的连接数异常问题

2009年8月30日 admin 没有评论

有客户说,他们通过connection pool监控发现weblogic92连接池中当前连接数(current capacity)小于初始连接数(initial capacity)。从现象上来说,给客户的直觉是:连接池初始化有问题,没有帮助他们初始化他们需要的那么多连接。但他同时发现,几个 connection pool中,其他pool没有问题。拿到问题,我也怀疑这可能是weblogic的一个bug,但随后从客户发送过来的日志中发现出问题的 connection被disable过。调查后发现问题的确和这个pool被disable过有关,那么为什么pool被disable后,会出现这样 的问题呢?

首先我们看看这个pool为什么会被disable? 手工强制suspend连接池、数据库关闭、网络不稳定等因素都可能成为connection pool被disable的诱因。从客户的日志中,我能看到大量的如下异常,
1:java.net.SocketException: 管道已断开 (errno:32)
2:weblogic.common.resourcepool.ResourceDisabledException: Pool JDBC Data Source-0 is disabled, cannot allocate resources to applications.

根据上面的异常,首先跟客户确认是否存在过数据库关闭、强制disable connection的操作,这些都被客户否定了,那么最大可能的原因就是网络不稳定,网络是好时坏的话,很容易造成weblogic连接池中到 database server的连接中断,从而导致connection pool被disable。

那么为什么连接中断会引起connection pool被disable呢?这里要谈到两个参数:CountOfTestFailuresTillFlush、 CountOfRefreshFailuresTillDisable。这两个参数在weblogic连接池实现中由于控制是否、何时flush或 disable连接池,两个都是指连续几次失败操作(test、refresh)后去flush或disable connection pool。注意:这是说的是连续,而不是间断,每次成功操作(test、refresh)后,这两个值都会被reset成0。默认情况下这两个值均为2, 即连续失败3(2+1)次后,connection pool会被flush或disable。两者的区别在于,flush用于清空connection pool中的所有连接(通常都是中断的connection),当pool状态仍保持在running状态,而对于后者,connection pool将会变成suspend。前者对于客户端而言,还可以从pool中reserve connection,reserve时,weblogic会尝试重现创建连接,如果创建连接成功,那么客户端就可以拿到可用的连接。而对于一个处于 suspend状态,客户端reserve connection的请求会直接被拒绝,收到的异常如下:
weblogic.common.resourcepool.ResourceDisabledException: Pool JDBC Data Source-0 is disabled, cannot allocate resources to applications

一个被disable的connection pool我们需要手工resume吗?比如数据库因为某些原因而突发关闭,数据库恢复后,我们是否需要手工去resume这个pool?不需 要,weblogic内部实现了连接池的自我健康检查功能,对于disable的connection pool,weblogic会每隔5秒钟(DEFAULT_SCAN_UNIT)去做一次连接尝试(尝试创建一个物理连接,如果连接成功,那么这个连接会 被直接放入连接池中,我们的问题就处在这儿),我们通过下面的复现过程来看看具体原因:

1:配置一个datasource,connection的连接数具体配置如下:


2:weblogic启动后,我们可以看到current capacity为15,此时connection pool刚被初始化,weblogic会根据initial capacity去创建相应数量的连接。此时如果我们关闭数据库,然后通过测试程序去获取连接,你会看到我们无法拿到连接(注意我们要选上 TestOnReserve),重复三次,再次去监控connection pool。因为三次test失败后,connection pool会被disable(状态为suspend),如下:


3:重启database。由于weblogic内部实现了connection pool的自检功能,对于disabled的connection pool,weblogic每隔5秒钟去做一次连接尝试,如果连接创建成功,新建连接会被放入连接池,同时resume连接池。通过监控我们可以看到,连 接池状态变成running,同时current capacity变成1,

4:启动多线程测试程序,模拟2个用户并发。第一个用户可以从connection pool中成功拿到连接,而第二个用户因为连接池的current capacity为1,无法直接从pool中拿到连接,这是连接池需要做扩展,而扩展的个数就是我们设定的capacity increment(20)。再来监控connection pool,我们就会看到连接池的current capacity为21,如下:

那么我们能不能通过参数配置不让connection pool不作disable呢? 我们前面所提到的两个参数:CountOfTestFailuresTillFlush、 CountOfRefreshFailuresTillDisable,可以实现这样的要求:

1 <internal-properties>
2 <property>
3 <name>CountOfTestFailuresTillFlush</name>
4 <value>10</value>
5 </property>
6 <property>
7 <name>CountOfRefreshFailuresTillDisable</name>
8 <value>20</value>
9 </property>
10 </internal-properties>

internal-properties用于定义一些weblogic internal的参数,这些参数无法在console上做配置。除了上面的这两个参数,我们还可以通过internal-properties配置如下几个参数:
TestConnectionsOnCreate
TestConnectionsOnRelease
HighestNumUnavailable
SecurityCacheTimeoutSeconds

通过上述分析,我们可以看到这个问题不是weblogic的bug,而是因为网络问题导致connection pool被disable,要彻底解决这个问题,可以通过网络分析工具查出网络问题,进而解决我们看到的这种现象。

Popularity: unranked [?]