2010-03-16 25 views
1

我們的系統設置包含兩個Weblogic 10.3服務器:一個承載表示層,另一個承載EJB。該系統運行在中等負載下的優質一段時間(一至數天),之後EJB方法從表示服務器到EJB服務器開始調用失敗,出現以下錯誤:Weblogic EJB調用在中等負載下隨着OptionalDataException而開始失敗

java.rmi.RemoteException: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: java.io.OptionalDataException 

堆棧跟蹤:

java.io.OptionalDataException 
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1349) 
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351) 
    at weblogic.utils.io.ChunkedObjectInputStream.readObject(ChunkedObjectInputStream.java:197) 
    at weblogic.rjvm.MsgAbbrevInputStream.readObject(MsgAbbrevInputStream.java:564) 
    at weblogic.utils.io.ChunkedObjectInputStream.readObject(ChunkedObjectInputStream.java:193) 
    at weblogic.jndi.internal.RootNamingNode_WLSkel.invoke(Unknown Source) 
    at weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:589) 
    at weblogic.rmi.cluster.ClusterableServerRef.invoke(ClusterableServerRef.java:230) 
    at weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:477) 
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363) 
    at weblogic.security.service.SecurityManager.runAs(Unknown Source) 
    at weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:473) 
    at weblogic.rmi.internal.wls.WLSExecuteRequest.run(WLSExecuteRequest.java:118) 

一旦遇到第一個OptionalDataException,所有後續調用都會失敗,結果相同。有些消息來源表明,這可能與羣集多點傳送端口被錯誤配置有關。但是,這些服務器不屬於羣集。

引導EJB服務器總是暫時解決問題,但問題似乎在一段時間後再次發生。

更新:看來,這個問題是不是相關在socket連接畢竟數量溢出(見下面我自己的答案)。在禁止網絡類加載之後,我們非常穩定地運行了一週,之後我們又開始在演示服務器上再次接收OptionalDataExceptions(下面的堆棧跟蹤)。很奇怪的是,系統一週工作正常,然後開始失敗。

javax.naming.CommunicationException [Root exception is java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 
    java.io.OptionalDataException] 
    at weblogic.jndi.internal.ExceptionTranslator.toNamingException(ExceptionTranslator.java:74) 
    at weblogic.jndi.internal.WLContextImpl.translateException(WLContextImpl.java:439) 
    at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:395) 
    at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:380) 
    at javax.naming.InitialContext.lookup(InitialContext.java:392) 
    ... 
Caused by: java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: 

    java.io.OptionalDataException 
    at weblogic.rjvm.ResponseImpl.unmarshalReturn(ResponseImpl.java:234) 
    at weblogic.rmi.cluster.ClusterableRemoteRef.invoke(ClusterableRemoteRef.java:348) 
    at weblogic.rmi.cluster.ClusterableRemoteRef.invoke(ClusterableRemoteRef.java:259) 
    at weblogic.jndi.internal.ServerNamingNode_1030_WLStub.lookup(Unknown Source) 
    at weblogic.jndi.internal.WLContextImpl.lookup(WLContextImpl.java:392) 
    ... 38 more 
Caused by: java.io.OptionalDataException 
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1349) 
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351) 
    at  
    weblogic.utils.io.ChunkedObjectInputStream.readObject(ChunkedObjectInputStream.java:197) 
    at weblogic.rjvm.MsgAbbrevInputStream.readObject(MsgAbbrevInputStream.java:564) 
    at  
weblogic.utils.io.ChunkedObjectInputStream.readObject(ChunkedObjectInputStream.java:193) 
    at weblogic.jndi.internal.RootNamingNode_WLSkel.invoke(Unknown Source) 
    at weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:589) 
    at weblogic.rmi.cluster.ClusterableServerRef.invoke(ClusterableServerRef.java:230) 
    at weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:477) 
    at   
weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363) 
    at weblogic.security.service.SecurityManager.runAs(Unknown Source) 
    at weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:473) 
    at weblogic.rmi.internal.wls.WLSExecuteRequest.run(WLSExecuteRequest.java:118) 
    ... 2 more 

我們獲得初始上下文相當的標準方式:

Properties p = new Properties(); 
p.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); 
p.put(Context.PROVIDER_URL, serverPath); 
Context context = new InitialContext(p); 

還調用任何獲得引用失敗,類似的OptionalDataException。單獨啓動演示服務器可以暫時解決問題。

+0

EJB服務器是否也同時拋出任何相應的異常,例如EOFException?只是試圖深入瞭解在服務器上調用EJB Remote還是在此之前失敗。 – JoseK 2010-03-17 05:52:08

+0

非常好的一點。我不是100%確定的,但我認爲請求在到達EJB服務器之前失敗 - 至少在EJB服務器日誌中沒有任何內容。日誌記錄級別已經提高了,所以如果這種情況再次發生,我們會確定的。服務器正在運行,並在問題發生時繼續處理其內部計劃任務,所以至少我們知道服務器能夠連接到數據庫等。 – MarkoU 2010-03-17 08:34:48

+0

關於通常發生此錯誤的羣集 - 您的意思是這兩臺服務器不是ANY羣集的一部分,還是不是SAME羣集的一部分?正如你所知道的很多URL都表明這個錯誤的Cluster多播干擾。 – JoseK 2010-03-17 11:33:02

回答

1

最後,OptionalDataExceptions是歷史記錄。簡而言之,在我們的應用程序代碼中,複雜的值對象(用作遠程方法調用的返回值)具有作爲內部字段的HashMap數據結構。將此字段的類型更改爲SynchronizedMap後,可選數據異常停止發生。看起來在遺留代碼的某個地方,這個Map是以非線程安全的方式處理的。

奇怪的是,這不會導致WLS 8.1出現問題,但會以某種方式導致WLS 10進入一個狀態,其中所有後續的遠程方法調用(包括JNDI查找)開始失敗。

1

最後我們找到了解決辦法(編輯:後來我們發現這不是問題的根源,而是一個單獨的嚴重問題,最終的解決方案請看下面的答案)。一旦我們開始收到下面的異常,我們上了事業的軌跡:

<BEA-000403> <IOException occurred on socket: Socket[addr=/x.x.x.x,port=3266,localport=7001] 
java.net.SocketException: Connection refused. 
java.net.SocketException: Connection refused 
at java.net.SocketInputStream.socketRead0(Native Method) 
at java.net.SocketInputStream.read(SocketInputStream.java:129) 
at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:887) 
at weblogic.socket.SocketMuxer.readReadySocket(SocketMuxer.java:859) 
at weblogic.socket.DevPollSocketMuxer.processSockets(DevPollSocketMuxer.java:120) 
at weblogic.socket.SocketReaderRequest.run(SocketReaderRequest.java:29) 
at weblogic.socket.SocketReaderRequest.execute(SocketReaderRequest.java:42) 
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:145) 
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:117) 

在演示服務器,這是一個不同的主機比EJB服務器上運行,我們有選擇

-Dweblogic.NetworkClassLoadingEnabled=true 

明顯可以從EJB服務器啓用類加載。我們不知道的是,使用此選項可能會導致打開大量網絡套接字。使用netstat,我們能夠發現有幾千個套接字處於CLOSE_WAIT或FIN_WAIT_2狀態。似乎除了類別之外,Web UI中的所有元素都是從EJB服務器加載的,儘管表示服務器上的war文件包含了所有這些元素。由於Weblogic在其啓動腳本中刪除了文件的ulimit,因此大量的套接字沒有導致「文件太多」的錯誤消息。通過使用測試服務器,我們發現用戶在Web UI上單擊一次即可在兩臺服務器之間打開30個插槽。

我們刪除了此選項,並將演示服務器上的戰爭重新包裝爲包含所有需要的類,從而消除了對網絡類加載的需求。這導致兩個服務器之間的套接字連接數從數千減少到1.

總結中,如果可能的話,儘量避免在Weblogic中加載網絡類。