Domanda

La nostra configurazione del sistema è costituito da due Weblogic 10.3 server: uno ospita il livello di presentazione e gli altri host della EJB. Il sistema funziona bene sotto carico moderato per qualche tempo (uno o più giorni) dopo il quale il metodo EJB chiama dal server presentazione alla partenza server EJB a fallire con il seguente errore:

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

traccia stack:

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)

Una volta che il primo OptionalDataException si incontra tutte le chiamate successive sicuro con lo stesso risultato. Alcune fonti suggeriscono che questo potrebbe essere correlato a raggrupparsi porta multicast essere configurato correttamente. Tuttavia, questi server non appartengono a un cluster.

Avviare il server EJB sempre risolve temporaneamente il problema, ma il problema sembra verificarsi di nuovo dopo qualche tempo.

Aggiorna : sembra che il problema è non relativi a un overflow del numero di connessioni socket dopo tutto (vedere la mia risposta qui sotto). Dopo non consentire classloading rete abbiamo corso molto costante per una settimana dopo che abbiamo iniziato a ricevere OptionalDataExceptions sul server di presentazione di nuovo (traccia dello stack di seguito). E 'molto strano che il sistema funziona bene per una settimana e poi inizia a fallire.

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

Si ottiene il contesto iniziale piuttosto il modo standard:

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

ha anche chiamato tutti i riferimenti ottenuti non riescono con un OptionalDataException simile. Avvio del server di presentazione da solo risolve temporaneamente il problema.

È stato utile?

Soluzione

Infine i OptionalDataExceptions sono storia. In breve, nel nostro codice applicativo un oggetto valore complesso (usato come valore di ritorno per le invocazioni a metodi remoti) aveva un datastructure HashMap come un campo interno. Dopo aver cambiato il tipo di questo campo per SynchronizedMap le OptionalDataExceptions fermato verificano. Sembra che da qualche parte nel codice legacy questa mappa è gestito in modo non thread-safe.

Quello che è strano è che questo ha causato alcun problema con WLS 8.1, ma in qualche modo causato WLS 10 entrare in uno stato in cui tutte le successive chiamate di metodo a distanza (tra cui ricerche JNDI) hanno cominciato a fallire.

Altri suggerimenti

Finalmente abbiamo trovato la soluzione a questo (Edit: in seguito abbiamo scoperto che questo non era la causa principale del problema, ma un problema serio a parte per la soluzione finale, si prega di vedere la risposta qui sotto.). Una volta che abbiamo iniziato a ricevere la seguente eccezione abbiamo ottenuto sui binari della causa:

<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)

Sul server presentazione, che è in esecuzione su un host diverso da quello del server EJB abbiamo avuto la possibilità

-Dweblogic.NetworkClassLoadingEnabled=true

per consentire, ovviamente, carico di classe dal server EJB. Quello che non sapevamo è che l'utilizzo di questa opzione può portare a un numero enorme di socket di rete che si apre. Utilizzando netstat siamo stati in grado di scoprire che diverse migliaia di zoccoli erano o in CLOSE_WAIT o FIN_WAIT_2 Stato. Sembra che tutti gli elementi nell'interfaccia utente web sono stati caricati dal server EJB in aggiunta alle classi nonostante il fatto che il file WAR sul server di presentazione conteneva tutti questi. L'enorme quantità di prese non ha provocato "troppi file" messaggi di errore in quanto Weblogic rimuove l'ulimit per i file nel suo script di avvio. Utilizzando un server di test abbiamo scoperto che un singolo clic sul web UI da parte dell'utente ha aperto circa 30 prese tra i due server.

Abbiamo rimosso questa opzione e riconfezionato la guerra sul server di presentazione per contenere tutte le classi necessarie eliminando così la necessità di classloading rete. Ciò ha determinato una diminuzione del numero di connessioni socket tra i due server da migliaia a 1.

In sintesi, evitare di classe di rete di carico in Weblogic, se possibile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top