Quelle est la cause de RMI appels de méthode à échouer par intermittence?
Longue histoire courte, j'ai un RMI le Serveur et le Client. Le Serveur et le Client sont capable de faire des appels RMI les uns sur les autres. Après que le Client se connecte au Serveur, le Serveur peut se faire de plusieurs centaines d'appels de méthode en succession rapide sur le Client.
Le problème est-ce - vers la fin d'un important lot de Serveur à Client appels de méthode, certains vont échouer parce que RMI prétend qu'il ne peut pas établir une connexion à partir du Serveur à Client, même si des centaines d'appels avant de réussir. Je ne peux pas poster tout le code réel, parce que ce projet est assez grande (environ 50k lignes), mais ici la trace de la pile de l'exception qui est lancée:
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
java.net.SocketException: Connection reset
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source)
at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at $Proxy0.findClassDefinition(Unknown Source)
at com.fabric.network.NetworkClassLoader.findClass(NetworkClassLoader.java:111)
at java.lang.ClassLoader.loadClass(Unknown Source)
at com.fabric.network.NetworkClassLoader.loadClass(NetworkClassLoader.java:131)
at java.lang.ClassLoader.loadClass(Unknown Source)
at com.fabric.network.MessageSocket$CustomObjectInputStream.resolveClass(MessageSocket.java:171)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at com.fabric.network.MessageSocket.receive(MessageSocket.java:118)
at com.fabric.application.driver.NodeRemoteDriver$IncomingMessageThread.run(NodeRemoteDriver.java:205)
Caused by: java.rmi.ConnectIOException: error during JRMP connection establishment; nested exception is:
java.net.SocketException: Connection reset
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source)
at $Proxy2.findClassDefinition(Unknown Source)
at com.fabric.network.ClassDefinitionCache.findClassDefinition(ClassDefinitionCache.java:78)
at com.fabric.management.host.NodeManagementServices.findClassDefinition(NodeManagementServices.java:231)
at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
at sun.rmi.transport.Transport$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at java.io.DataInputStream.readByte(Unknown Source)
... 21 more
Encore une fois, désolé je ne peux pas fournir beaucoup de code, mais je ne suis pas nécessairement en demander un correctif de code - je veux juste envelopper ma tête autour de pourquoi ce qui se passe.
MODIFIER
Ajouté le plein de trace de pile.
Ma question peut être un peu bête mais avez-vous vérifié si il y a des exceptions sur le côté client?
Oui, il est. Ce est une exception sur le côté client.
Merci de poster le reste de la trace de la pile. Nous avons besoin de voir la prochaine", causées par' partie.
Tout le truc est là, maintenant. Merci de prendre un coup d'oeil!
OriginalL'auteur CodeBlind | 2012-05-02
Vous devez vous connecter pour publier un commentaire.
Ok, donc après presque tirant tous mes cheveux, il s'avère que le RMI a été d'essayer de s'ouvrir trop grand nombre de ports. Je suis en utilisant une mesure
RMISocketFactory
mise en œuvre sous le capot. Cette coutume de la mise en œuvre est un singleton, donc je ne pense pas que c'était nécessaire pour mettre en œuvrehashCode()
etequals()
. Un très douloureuse erreur en effet...S'avère que le RMI ne pas réutiliser les sockets si RMI détermine que le support, elle doit créer doit être créé par un
RMISocketFactory
qui n'est pas équivalent à l'usine qui a créé le socket qu'il veut réutiliser. RMI s'appuie surequals()
ethashCode()
pour effectuer cette vérification. Une fois que j'ai correctement mis en œuvre ces deux méthodes dans mon socket personnalisé usine, ces problèmes intermittents s'en alla.La description de cette question peut être trouvée ici:
http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/faq.html
En tout cas, merci à tous de prendre un regard sur ce, je vous remercie de votre temps!
Des Informations Supplémentaires
Une question secondaire que je n'avais pas remarqué avant était que le
ServerSocket
j'ai été à l'aide de la file d'attente de l'espace pour la réception des demandes de connexion, ce qui a également contribué à l'connexions chuté. En utilisant le constructeurnew ServerSocket(port, newConnectionQueueSize, bindAddress)
avec une plus grandenewConnectionQueueSize
contribué à la résolution de ce problème ainsi.OriginalL'auteur CodeBlind