Dans un filtre ISAPI, quelle est une bonne approche pour un fichier de journal commun pour plusieurs processus?

StackOverflow https://stackoverflow.com/questions/1511290

Question

J'ai un filtre ISAPI qui s'exécute sur IIS6 ou 7. Lorsqu'il y a plusieurs processus de travail ("web jardin"), le filtre sera chargé et exécuté dans chaque w3wp.exe.

Comment puis-je permettre efficacement au filtre de enregistrer ses activités dans un seul fichier de journaux consolidé?

  • Les messages de journal des différents processus (simultanés) ne doivent pas interférer les uns avec les autres. En d'autres termes, un seul message de journal émis dans l'un des w3wp.exe doit être réalisé en tant que ligne contiguë unique dans le fichier journal.

  • Il devrait y avoir une affirmation minimale pour le fichier de journaux. Les sites Web peuvent desservir des centaines de demandes par seconde.

  • Une commande de temps stricte est préférée. En d'autres termes, si le processus W3wp.exe # 1 émet un message à T1, le processus # 2 émet un message à T2, puis le processus # 1 émet un message à T3, les messages doivent apparaître dans le bon ordre de temps dans le fichier journal.

L'approche actuelle que j'ai est que chaque processus possède un fichier de journaux distinct. Cela présente des inconvénients évidents.

Quelques idées:

  • Nommez l'un des W3wp.exe pour être "propriétaire du fichier de journaux" et envoyez tous les messages de journal via ce processus spécial. Cela a des problèmes en cas de recyclage des processus des travailleurs.

  • Utilisez un MUTEX OS pour protéger l'accès au fichier log. Est-ce que ce Perf est suffisant? Dans ce cas, chaque w3wp.exe aurait un fichier sur le même fichier de système de fichiers. Dois-je flancher le fichier de journaux après chaque écriture? Est-ce que ça va marcher?

Aucune suggestion?

Était-ce utile?

La solution

Au début, j'allais dire que j'aime le mieux votre approche actuelle, car chaque processus ne partage rien, puis j'ai réalisé que, eh bien, ils partagent probablement tous le même disque dur en dessous. Il y a donc encore un goulot d'étranglement où se produit les affirmations. Ou peut-être que le système d'exploitation et les contrôleurs de disque dur sont vraiment intelligents à l'idée de gérer cela?

Je pense que ce que vous voulez faire, c'est que l'écriture du journal ne ralentit pas les fils qui font le vrai travail.

Alors, exécutez un autre processus sur la même machine (priorité inférieure?) Qui écrit réellement les messages de journal au disque. Communiquez à l'autre processus en utilisant Not UDP comme suggéré, mais plutôt la mémoire que les processus partagent. Également connu, confus, comme un fichier mappé de mémoire. Plus à propos Fichiers mappés de mémoire. Dans mon entreprise, nous avons trouvé que les fichiers mappés de mémoire étaient beaucoup plus rapides que Loopback TCP / IP pour la communication sur la même boîte, donc je suppose que ce serait plus rapide que UDP aussi.

Ce que vous avez réellement dans votre mémoire partagée pourrait être, pour commencer, une file d'attente STD :: où les poussées et les pops sont protégés à l'aide d'un mutex. Vos threads Isapi saisiraient le mutex pour mettre les choses dans la file d'attente. Le processus de journalisation saisirait le mutex pour retirer les choses de la file d'attente, relâcher le mutex, puis rédiger les entrées sur le disque. Le mutex n'est protégé que la mise à jour de la mémoire partagée, et non la mise à jour du fichier, il semble donc en théorie que le mutex se tiendrait pour une période plus brillante, créant moins d'un goulot d'étranglement.

Le processus de journalisation pourrait même réorganiser l'ordre de ce qu'il écrit pour obtenir les horodatages en ordre.

Voici une autre variation: continu pour avoir un journal séparé pour chaque processus, mais avoir un thread de bûcheron dans chaque processus afin que le thread à temps critique principal n'aient pas à attendre que la journalisation se produise afin de poursuivre ses travaux.

Le problème avec tout ce que j'ai écrit ici est que l'ensemble du système - matériel, système d'exploitation, la façon dont le cache CPU L1 / L2 multicore fonctionne, votre logiciel - est trop complexe pour être facilement prévisible en le pensant juste à travers. Codez quelques applications de preuve de concept simples, instrument avec quelques horaires et essayez-les sur le matériel réel.

Autres conseils

La connexion à une base de données aurait-elle du sens ici?

J'ai utilisé un système de journalisation basé sur UDP dans le passé et j'étais satisfait de ce type de solution.

Les journaux sont envoyés via UDP à un processus de collecteur logarithmique dont il est responsable de l'enregistrer dans un fichier régulièrement.

Je ne sais pas si cela peut fonctionner dans votre contexte élevé Perf, mais j'étais satisfait de cette solution dans une application moins sous-stress.

J'espère que ça aide.

Plutôt qu'un MUTEX OS pour contrôler l'accès au fichier, vous pouvez simplement utiliser les mécanismes de verrouillage des fichiers Win32 avec LockFile () et UnlockFile ().

Ma suggestion est d'envoyer des messages de manière asynchrone (UDP) à un processus qui prendra en charge l'enregistrement du journal.
Le processus sera:
- Un récepteur de thread met les messages dans une file d'attente;
- Un thread est responsable de la suppression des messages de la file d'attente dans une liste de temps ordonnée;
- Un thread Monitor Messages dans la liste et seuls les messages avec durée supérieure au minimum doivent être enregistrés dans le fichier (pour éviter que un message retardé soit écrit de commande).

Vous pouvez continuer à vous connecter pour séparer les fichiers et trouver / écrire un outil pour les fusionner plus tard (peut-être automatisé, ou vous pouvez simplement l'exécuter au moment où vous souhaitez utiliser les fichiers.)

Traçage des événements pour Windows, inclus dans Windows Vista et plus tard, offre une belle capacité à cela.

Extrait:

Le traçage des événements pour Windows (ETW) est une installation de traçage au niveau du noyau efficace qui vous permet de enregistrer les événements du noyau ou de définir l'application dans un fichier journal. Vous pouvez consommer les événements en temps réel ou à partir d'un fichier journal et les utiliser pour déboguer une application ou pour déterminer où les problèmes de performances se produisent dans l'application.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top