En un filtro ISAPI, ¿cuál es un buen enfoque para un archivo de registro común para múltiples procesos?

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

Pregunta

Tengo un filtro ISAPI que se ejecuta en IIS6 o 7. Cuando hay múltiples procesos de trabajadores ("Jardín web"), el filtro se cargará y se ejecutará en cada w3wp.exe.

¿Cómo puedo permitir que el filtro registre sus actividades en un solo archivo de registro consolidado?

  • Los mensajes de registro de los diferentes procesos (concurrentes) no deben interferir entre sí. En otras palabras, un solo mensaje de registro emitido desde cualquiera de los w3wp.exe debe realizarse como una sola línea contigua en el archivo de registro.

  • Debe haber una contención mínima para el archivo de registro. Los sitios web pueden cumplir 100 de solicitudes por segundo.

  • Se prefiere el pedido de tiempo estricto. En otras palabras, si el proceso w3wp.exe #1 emite un mensaje en T1, el proceso #2 emite un mensaje en T2, entonces el proceso #1 emite un mensaje en T3, los mensajes deben aparecer en el orden de tiempo adecuado en el archivo de registro.

El enfoque actual que tengo es que cada proceso posee un archivo de registro separado. Esto tiene inconvenientes obvios.

Algunas ideas:

  • Nomine a uno de los w3wp.exe para que sea "propietario del archivo de registro" y envíe todos los mensajes de registro a través de ese proceso especial. Esto tiene problemas en caso de reciclaje de procesos de trabajadores.

  • Use un OS Mutex para proteger el acceso al archivo de registro. ¿Es esto lo suficiente? En este caso, cada w3wp.exe tendría un archivo en el mismo archivo del sistema de archivos. ¿Debo hacer el archivo de registro después de cada escritura? esto funcionara?

¿alguna sugerencia?

¿Fue útil?

Solución

Al principio iba a decir que me gusta más su enfoque actual, porque cada proceso no comparte nada, y luego me di cuenta de que, bueno, probablemente todos compartan el mismo disco duro debajo. Entonces, todavía hay un cuello de botella donde ocurre la contención. ¿O tal vez el sistema operativo y los controladores del disco duro son realmente inteligentes para manejar eso?

Creo que lo que quieres hacer es escribir el registro, no reducir la velocidad de los hilos que están haciendo el trabajo real.

Entonces, ejecute otro proceso en la misma máquina (¿menor prioridad?) Que realmente escribe los mensajes de registro en el disco. Comuníquese con el otro proceso utilizando no UDP como se sugiere, sino en la memoria que comparten los procesos. También conocido, confusamente, como un archivo mapeado de memoria. Más sobre archivos mapeados de memoria. En mi empresa, hemos encontrado que los archivos mapeados de memoria son mucho más rápidos que el bucleback TCP/IP para la comunicación en el mismo cuadro, por lo que supongo que también sería más rápido que UDP.

Lo que realmente tienes en tu memoria compartida podría ser, para empezar, una cola STD :: donde los empujes y los pops están protegidos con un mutex. Sus hilos ISAPI agarrarían el Mutex para poner las cosas en la cola. El proceso de registro agarraría el mutex para sacar las cosas de la cola, liberar el mutex y luego escribir las entradas al disco. El Mutex solo está protegido por la actualización de la memoria compartida, no la actualización del archivo, por lo que parece en teoría que el Mutex se mantendrá durante un tiempo más breve, creando menos cuello de botella.

El proceso de registro incluso podría reorganizar el orden de lo que está escribiendo para poner en orden las marcas de tiempo.

Aquí hay otra variación: Contine tener un registro separado para cada proceso, pero tenga un hilo de registrador dentro de cada proceso para que el hilo crítico de tiempo principal no tenga que esperar a que ocurra el registro para continuar con su trabajo.

El problema con todo lo que he escrito aquí es que todo el sistema (hardware, sistema operativo, la forma en que funciona la caché de CPU L1/L2 multinúcleo, su software) es demasiado complejo para ser fácilmente predecible por un solo pensamiento. ENFOREZAR algunas aplicaciones simples de prueba de concepto, instrumentarlas con algunos tiempos y pruébalas en el hardware real.

Otros consejos

¿Tendría sentido el registro en una base de datos aquí?

I've used a UDP-based logging system in the past and I was happy with this kind of solution.

The logs are sent via UDP to a log-collector process which his in charge of saving it to a file on a regular basis.

I don't know if it can work in your high-perf context but I was satisfied with that solution in a less under-stress application.

I hope it helps.

En lugar de un sistema operativo MUTEX para controlar el acceso al archivo, solo puede usar mecanismos de bloqueo de archivos WIN32 con LockFile () y UplockFile ().

Mi sugerencia es enviar mensajes de forma asincrónica (UDP) a un proceso que se encargará de grabar el registro.
El proceso:
- Un receptor de hilo pone los mensajes en una cola;
- Un hilo es responsable de eliminar los mensajes de la cola que pone en una lista de tiempo ordenada;
- Un monitor de subprocesos en la lista y solo mensajes con longitud de tiempo mayor que el mínimo deben guardar en el archivo (para evitar que se escriba un mensaje retrasado fuera de servicio).

Puede continuar iniciando sesión para separar los archivos y encontrar/escribir una herramienta para fusionarlos más tarde (tal vez automatizado, o simplemente podría ejecutarlo en el punto que desea usar los archivos).

Rastreo de eventos para Windows, incluido en Windows Vista y más tarde, proporciona una buena capacidad para esto.

Extracto:

El rastreo de eventos para Windows (ETW) es una instalación eficiente de rastreo de nivel de núcleo que le permite registrar los eventos de núcleo o definidos por la aplicación en un archivo de registro. Puede consumir los eventos en tiempo real o desde un archivo de registro y usarlos para depurar una aplicación o para determinar dónde ocurren problemas de rendimiento en la aplicación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top