46 votes

System.IO.FileSystemWatcher pour surveiller un dossier de serveur réseau - Considérations sur les performances

Je veux surveiller les modifications d'une arborescence de dossiers sur un serveur réseau. Les fichiers ont tous une extension spécifique. Il y a environ 200 dossiers dans l'arbre et environ 1200 fichiers avec l'extension que je surveille.

Je ne peux pas écrire un service à exécuter sur le serveur (interdit !), la solution doit donc être locale pour le client. La rapidité d'exécution n'est pas particulièrement importante. Je peux vivre avec un retard d'une minute ou plus dans les notifications. Je surveille la création, la suppression, le renommage et les modifications.

L'utilisation de l'outil .NET System.IO.fileSystemWatcher créerait-elle une charge importante sur le serveur ?

Que diriez-vous de 10 surveillants distincts pour réduire le nombre de dossiers/fichiers surveillés (de 700 dossiers à 200, de 5500 fichiers à 1200 au total) ? Je pense à un remaniement du serveur pour mettre les fichiers surveillés sous un seul arbre. Je n'aurai peut-être pas toujours cette option, d'où l'équipe de surveillants.

Je suppose que l'autre solution consiste à vérifier périodiquement si le FSW crée une charge excessive sur le serveur, ou s'il ne fonctionne pas pour tout un tas de raisons de type SysAdmin.

Y a-t-il une meilleure façon de procéder ?

77voto

mdb Points 20629

Du point de vue de la charge du serveur, l'utilisation de l'option IO.FileSystemWatcher pour les notifications de changement à distance dans le scénario que vous décrivez est probablement la méthode la plus efficace possible. Elle utilise le FindFirstChangeNotification y ReadDirectoryChangesW Les fonctions internes de l'API Win32, qui communiquent à leur tour avec le redirecteur de réseau de manière optimisée (en supposant un réseau Windows standard : si un redirecteur tiers est utilisé et qu'il ne prend pas en charge la fonctionnalité requise, les choses ne fonctionneront pas du tout). Le wrapper .NET utilise également des entrées/sorties asynchrones, ce qui garantit une efficacité maximale.

Le seul problème de cette solution est qu'elle n'est pas très fiable. Outre le fait de devoir faire face à des connexions réseau temporairement interrompues (ce qui n'est pas un gros problème, puisque IO.FileSystemWatcher déclenchera dans ce cas un événement d'erreur que vous pourrez gérer), le mécanisme sous-jacent présente certaines limitations fondamentales. Extrait de la documentation MSDN pour les fonctions de l'API Win32 :

  • ReadDirectoryChangesW échoue avec ERROR_INVALID_PARAMETER lorsque la longueur du tampon est supérieure à 64 Ko et que l'application surveille un répertoire sur le réseau. Ceci est dû à une limitation de la taille des paquets avec les protocoles de partage de fichiers sous-jacents.

  • Les notifications peuvent ne pas être renvoyées lors de l'appel FindFirstChangeNotification pour un système de fichiers distant

En d'autres termes, en cas de charge élevée (lorsque vous avez besoin d'une grande mémoire tampon) ou, pire, dans des circonstances aléatoires non spécifiées, vous risquez de ne pas recevoir les notifications attendues. C'est même un problème avec les surveillants de systèmes de fichiers locaux, mais c'est beaucoup plus problématique sur le réseau. Une autre question ici sur SO détaille un peu plus les problèmes de fiabilité inhérents à l'API.

Lorsque vous utilisez des surveillants de systèmes de fichiers, votre application doit être capable de gérer ces limitations. Par exemple :

  • Si les fichiers que vous recherchez ont des numéros de séquence, enregistrez le dernier numéro de séquence pour lequel vous avez reçu une notification, afin de pouvoir rechercher les "trous" dans les notifications futures et traiter les fichiers pour lesquels vous n'avez pas reçu de notification ;

  • Lorsque vous recevez une notification, effectuez toujours une analyse complète du répertoire. Cela peut sembler mauvais, mais comme l'analyse est pilotée par les événements, elle est beaucoup plus efficace que l'interrogation ordinaire. De plus, tant que vous maintenez le nombre total de fichiers dans un seul répertoire, ainsi que le nombre de répertoires à analyser, en dessous de mille environ, l'impact de cette opération sur les performances devrait être assez minime de toute façon.

La mise en place d'auditeurs multiples est à éviter autant que possible : cela ne fera qu'empirer les choses moins fiable...

Bref, si vous voulez absolument tienen pour utiliser des surveillants de système de fichiers, les choses peuvent fonctionner correctement tant que vous êtes conscient des limitations, et ne vous attendez pas à une notification 1:1 pour chaque fichier modifié/créé.

Donc, si vous avez d'autres options (essentiellement, faire en sorte que le processus d'écriture des fichiers vous notifie d'une manière non basée sur le système de fichiers : n'importe quelle méthode RPC régulière sera une amélioration...), celles-ci valent vraiment la peine d'être examinées du point de vue de la fiabilité.

11voto

Nick Randell Points 4133

J'ai utilisé les surveillants du système de fichiers en C# un certain nombre de fois. La première fois que je les ai utilisés, ils ont cessé de fonctionner, principalement parce que je traitais les modifications dans le fil de discussion qui avait signalé la modification.

Maintenant, je pousse simplement le changement dans une file d'attente et je traite la file d'attente sur un autre thread. Cela semble résoudre le problème que j'avais à l'origine. Pour votre problème, vous pourriez avoir plusieurs observateurs qui poussent sur la même file d'attente.

Cependant, je ne l'ai pas utilisé avec votre type de problème.

3voto

Treb Points 11153

D'après mon expérience, un FSW ne crée pas de trafic réseau élevé. Cependant, s'il y a un problème de performance, votre approche consistant à utiliser plusieurs surveillants et à réduire le nombre de dossiers à surveiller semble raisonnable.

J'ai eu de gros problèmes avec FSW sur les lecteurs réseau, cependant : La suppression d'un fichier générait toujours l'événement d'erreur, jamais l'événement de suppression. Je n'ai pas trouvé de solution, donc j'évite désormais d'utiliser FSW s'il existe un moyen de contourner ce problème...

2voto

Jim Burger Points 3166

El La documentation MSDN indique que vous pouvez utiliser le composant FileSystemWatcher pour surveiller les modifications du système de fichiers sur un réseau. lecteur .

Il indique également que le composant watcher écoute les notifications de changement de système de fichiers plutôt que d'interroger périodiquement le lecteur cible pour connaître les changements.

Sur cette base, la quantité de trafic réseau dépend entièrement de la fréquence à laquelle vous pensez que le contenu de ce lecteur réseau va changer. Le composant FSW n'augmentera pas le niveau de trafic réseau.

-1voto

Chris Points 8576

Je ne pense pas qu'il y ait une sorte d'état actif ou de communication entre l'ordinateur avec le FSW et l'ordinateur dont l'emplacement est surveillé. En d'autres termes, le FSW n'envoie pas de ping à l'OS en réseau pour vérifier le fichier.

On pourrait imaginer qu'un message ou un événement est seulement soulevées/envoyées au TISF en réseau lorsqu'un changement se produit.

Mais ce ne sont que des spéculations. :)

0 votes

Comment le client peut-il savoir que quelque chose a changé sur le serveur s'il ne lui envoie pas un ping ? A priori, le FSW ne lance pas de processus sur le serveur. Pourtant, AFIK n'est pas grand chose dans ce cas.

1 votes

Nous avons une réponse maintenant, mais pour répondre à votre question : le TSF enverrait une demande à l'ordinateur pour qu'il soit averti lorsque le fichier change. Vous ne demandez pas sans cesse à un magazine s'il a déjà sorti un nouveau numéro, vous vous abonnez une fois et ils vous envoient les nouveaux numéros lorsqu'ils sont publiés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X