Weblogci10中关于managed、admin server之间Http连接超时的问题
客户提了这么个问题: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。如果我们作了设定,这两个值即读超时、连接超时都会生效。这两个值可以用于解决上述的问题。