web-dev-qa-db-fra.com

Dépannage des connexions bloquées dans l'état CLOSE_WAIT

J'ai une Java exécutée dans WebLogic 11g sous Windows qui, après plusieurs jours, ne répond plus. Un symptôme suspect que j'ai remarqué est qu'un grand nombre de connexions (environ 3000) apparaissent dans netstat avec un état CLOSE_WAIT même lorsque le serveur est inactif. Étant donné que le serveur d'applications gère les connexions client, je ne suis pas sûr de la cause de ce problème. serveur, mais je crois que ces connexions se ferment correctement. Qu'est-ce qui pourrait provoquer cela et comment résoudre un problème comme celui-ci?

23
Rob H

Le problème était un bogue déclenché en définissant "Utiliser JSSE SSL" sur true dans webLogic. L'utilisation de la propre implémentation SSL de WebLogic au lieu de JSSE n'est pas un problème pour notre application, j'ai donc simplement décoché ce paramètre et le problème a disparu.

2
Rob H

J'ai eu le même problème et j'ai étudié les sockets pour se débarrasser de ce problème.

Permettez-moi de dire quelques mots, mais avant je dois dire que je ne suis pas un programmeur Java.

Je n'expliquerai pas ce qu'est close_wait, car Brian White a déjà dit tout ce qui devait être dit.

Pour éviter close_wait, vous devez vous assurer que votre serveur ne ferme pas la connexion après avoir renvoyé la réponse, car celui qui se déconnecte est bloqué dans close_wait et time_wait. Donc, si votre serveur est bloqué dans close_wait, il m'indique qu'il se déconnecte après avoir envoyé la réponse.

Vous devriez éviter cela en faisant quelques choses.

1 - Si votre application cliente n'utilise pas le protocole http 1.1, vous devez la configurer pour l'utiliser à cause du 'keep-alive Option d'en-tête http.

2 - Si votre client exécute http 1.1 et que cela ne fonctionne pas, ou, si vous devez utiliser http 1.0, vous devez définir la propriété d'en-tête de demande de connexion:

connection: keep-alive

Cela indique au serveur que ni le client ni le serveur ne doivent se déconnecter après avoir terminé une demande. Ce faisant, votre serveur ne se déconnectera pas après chaque demande qu'il recevra.

3 - Dans votre client, réutilisez votre socket. Par exemple, si vous créez un grand nombre de clients de sockets dans une boucle, vous devez créer une socket une fois et les utiliser à chaque fois que vous devez envoyer une demande. L'approche que j'ai utilisée dans mon application est d'avoir un pool de sockets et d'obtenir un socket disponible (qui est déjà connecté au serveur et qui a la propriété keep-alive). Ensuite je l'utilise et quand j'ai fini je le remets dans la piscine pour être réutilisable.

4 - Si vous avez vraiment besoin de vous déconnecter après l'envoi d'une demande, assurez-vous que votre client le fait et conservez le connection: keep-alive.

Et oui, vous pouvez rencontrer des problèmes lorsque vous avez beaucoup de close_waits ou de time_waits côté serveur.

Consultez ce [lien] [1] qui explique ce que keep-alive est.

J'espère que cela a été utile. Avec ces choses, j'ai réussi à résoudre mon problème.

[1]: http://www.w3.org/Protocols/HTTP/1.1/draft-ietf-http-v11-spec-01.html#Persistent Connexions

19
Rafael Colucci

CLOSE_WAIT est l'état dans lequel la machine d'état locale TCP se trouve lorsque l'hôte distant envoie un FIN (ferme sa connexion) mais l'application locale n'a pas fait de même et a envoyé une réponse FIN. C'est toujours possible pour la machine locale d'envoyer des données à ce stade bien que le client ne puisse pas les recevoir (à moins qu'il n'ait fait qu'une demi-fermeture sur la connexion).

Lorsque l'hôte distant se ferme (envoie une FIN), votre application locale recevra un événement quelconque (c'est un événement "read" sur le socket de la bibliothèque C de base) mais la lecture de cette connexion renverra une erreur pour indiquer que le la connexion est fermée. À ce stade, l'application locale doit fermer la connexion.

Je sais peu de choses sur Java et rien sur WebLogic mais je suppose qu'il est possible que l'application ne gère pas correctement l'erreur de lecture et ne ferme donc jamais la connexion.

17
Brian White

Le CLOSE_WAIT status signifie que l'autre côté a initié une fermeture de connexion, mais l'application du côté local n'a pas encore fermé le socket.

Il semble que vous ayez un bug dans votre application locale.

4
caf

Cela peut signifier que vous n'appelez pas "close" sur un socket à partir de votre appel accept ().

1
rogerdpack

J'ai trouvé cette citation sur les pileups de CLOSE_WAIT: "Quelque chose empêche la progression de se produire dans la session HTTP (nous sommes bloqués, donc ne finissons jamais par appeler close), ou un bug a été introduit qui empêche la fermeture du socket. Il y a un certain nombre des façons dont cela peut se produire. "

Pensez: Existe-t-il un moyen de bloquer votre application lors du traitement d'une demande? Ou WebLogic lui-même?

Examinez: pouvez-vous faire Java (kill -SIGQUIT peut être utilisé pour cela sur la JVM Oracle pour Linux) pour essayer de voir si en fait certains de vos threads sont bloqués?

Examinez le côté client: Tout d'abord, recherchez l'adresse IP ou le nom d'hôte des clients qui sont connectés aux sockets CLOSE_WAIT. Ensuite, voyez si quelque chose de suspect se produit sur ces clients.

1
Robin Green