application serveur en mode dégradé

application serveur en mode dégradé - C - Programmation

Marsh Posté le 09-12-2011 à 09:41:45    

Bonjour,
 
Nous déployons actuellement une application serveur chez un de nos clients dont l'infrastructure réseau est assez capricieuse. Il arrive en effet que pendant plusieurs heures, des paquets IP se perdent (parfois jusqu'à 100% de paquets perdus).
Les clients de cette application sont des modules embarqués programmés pour se connecter automatiquement au serveur. En cas d’échec ou de rupture de connexion, ils réessaient à intervalle régulier.
Les clients comme le serveur tournent sous Linux.
 
Le souci, c'est que dans ces phases où le réseau n'est plus fiable, le serveur se relance inopinément, ce qui génère des alarmes non voulues. D'après les fichiers de log du serveur, voici ce que j'ai pu constater :
1 -  le processus en interface avec les clients s'arrête brutalement, sans entrer en phase d'arrêt propre. Le fichier de log correspondant ne montre rien d'anormal, hormis qu'il s'interrompt subitement. Il ne semble pas y avoir de segment violation.
2 - le thread qui gère les connexions reste parfois sans rien faire pendant 30 secondes. Je suis quasiment certain que ces 30 secondes sont passées dans le close() d'une socket. Je suspecte un timeout de protocole (TCP ?) car l'interruption dure exactement 30 secondes. J'imagine que lors de la fermeture, le protocole prévoit l'émission d'un message mais que les problèmes réseau font que l'on perd ce message. Par conséquent, il n'y a pas de réponse et le timeout fait le reste.
 
J'aimerais blinder l'application du serveur pour qu'au moins il ne se relance pas, mais mes connaissances en réseau sont assez limitées. Donc mes questions :
Pour le point 1 : pour quelles raisons le processus pourrait-il subitement s'arrêter à cause d'un réseau perturbé ?
Pour le point 2 : si c'est vraiment un problème de timeout, y a-t-il un moyen de réduire le délai de 30 secondes à un délai plus court lorsque le réseau devient perturbé ?
 
Je ne poste pas de code pour l'instant car l'application est assez volumineuse et elle fonctionne normalement lorsque le réseau tient la route. Ce n'est pas un bug logiciel qui est à l'origine de mon problème, je souhaite juste introduire plus de sécurité pour gérer une situation dégradée.
 
Merci d'avance !!
 
 
Avez vous des idées ?

Reply

Marsh Posté le 09-12-2011 à 09:41:45   

Reply

Marsh Posté le 10-12-2011 à 02:11:24    

Le timeout TCP se règle avec sysctl : net.ipv4.tcp_fin_timeout = 30
La valeur par défaut est souvent de 60, et une bonne fourchette est entre 15 et 30.
Ce pendant, je ne suis pas sûr que ce soit une bonne idée de trop le diminuer.
Cette valeur permet justement d'éviter de couper prématurément une connexion quand le réseau à des problèmes.  
 
Le réduire va juste précipiter le problème mais ne le règlera pas.
 
Il doit y avoir dans le code du serveur, une mauvaise gestion des erreurs TCP, ce qui doit probablement générer une "unhandled exception" qui fait planter le programme.
 
Sans savoir comment est codé le serveur je ne vois pas quoi dire de plus.


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 10-12-2011 à 17:35:48    

Merci Mara's dad.
J'avais vu la variable tcp_fin_timeout, dont la définition semblait correspondre à mon problème. Mais sa valeur est effectivement de 60. Et je ne vois pas le rapport avec les 30 secondes de délai que je rencontre. Et j'avoue que je n'aime pas l'idée d'aller bidouiller dans les paramètres TCP, au risque de rajouter d'autres problèmes.
 
L'hypothèse d'une exception non gérée pourrait tenir la route, mais j'utilise l'API socket en langage C, et à ma connaissance elle ne lance pas d'exceptions.


Message édité par shaoyin le 10-12-2011 à 21:06:44
Reply

Marsh Posté le 12-12-2011 à 10:59:52    

Je m'auto-réponds, mais si cela peut servir à quelqu'un d'autre...
 
Concernant le problème du close() qui reste bloqué pendant 30 secondes, je pense avoir trouvé l'origine.
C'est simplement que j'avais configuré ma socket pour limiter le risque de perte de données (SO_LINGER paramétré à 30 secondes). Donc la solution, c'est de passer ce paramètre à 0 juste avant le close lorsqu'il y a des perturbations réseau.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed