En mi trabajo, tengo seis servicios de Windows de los cuales soy responsable, escritos en C# 2003. Cada uno de estos servicios contiene un temporizador que dispara cada minuto, donde la mayoría de sus el trabajo sucedeServicio de Windows Aumento del consumo de CPU
Mi problema es que, a medida que estos servicios se ejecutan, comienzan a consumir más y más tiempo de CPU en cada iteración del ciclo, incluso si no hay un trabajo significativo para ellos (es decir, están inactivos, buscando en la base de datos algo que hacer). Cuando se inician, cada servicio usa un promedio de (aproximadamente) 2-3% de 4 CPUs, lo cual está bien. Después de 24 horas, cada servicio consumirá un procesador completo mientras dure su ciclo.
¿Alguien puede ayudar? No sé qué podría estar causando esto. Nuestra solución actual es reiniciar los servicios una vez al día (se cierran, un script ve que están desconectados y los reinicia a las 3AM aproximadamente). Pero esta no es una solución a largo plazo; mi preocupación es que a medida que los servicios se vuelven más activos, reiniciarlos una vez al día puede no ser suficiente ... pero como hay una penalización de arranque significativa (todos usan NHibernate para acceso a datos), a medida que se vuelven más ocupados, exactamente lo que don ' t desea estar haciendo es reiniciarlos con más frecuencia.
@akmad: Es cierto, es muy difícil.
- Sí, un servicio ejecutado de forma aislada mostrará el mismo síntoma a lo largo del tiempo.
- No, no es así. Hemos visto eso. Esto puede suceder a las 10 AM o a las 6 PM o en el medio de la noche. No hay consistencia.
- Hacemos; y estan. Los servicios están haciendo exactamente lo que deberían ser, y nada más.
- Desafortunadamente, eso requiere conocimiento previo de cuándo los servicios van a estar maximizando las CPU, lo que ocurre en un cronograma impredecible, y nunca muy rápido ... lo que hace las cosas doblemente difíciles, porque mi jefe las ejecutará y reiniciará cuando comienzan a tener problemas sin pensar en problemas de depuración.
- No, están usando una cantidad bastante constante de RAM (aproximadamente 60-80 MB cada uno, de 4 GB en la máquina).
Buenas sugerencias, pero puede estar seguro, hemos probado todas las soluciones habituales. Lo que espero es que este sea un problema de .NET que alguien pueda saber, que podamos resolver. La solución de mi jefe (que enfáticamente no quiero implementar) es poner un campo en la base de datos que retiene varias veces para que los servicios se reinicien durante el día, para que pueda solucionar el problema y no pensar en ello . Estoy buscando desesperadamente la causa del problema real para poder solucionarlo, porque esa solución se convertirá en un desastre en unos seis meses.
@Yaakov Ellis: Cada uno de ellos tiene una función diferente. Uno lee los registros de una base de datos Oracle en otro lugar; otro procesa esos registros y transfiere archivos pertenecientes a esos registros a nuestro sistema; un tercero verifica esos archivos para asegurarse de que sean lo que esperamos que sean; otro es un servicio de mantenimiento que constantemente revisa cosas como el espacio en disco (que tenemos suficiente) y sondea otros servidores para asegurarse de que estén vivos; uno se está ejecutando solo para asegurarse de que todos estos otros estén ejecutándose y haciendo su trabajo, monitorea e informa errores, y reinicia todo lo que no haya podido mantener todo el sistema funcionando las 24 horas del día.
Por lo tanto, si me pregunta qué pienso que está preguntando, no, no hay nada en común con todos estos servicios (aparte del acceso a la base de datos a través de NHibernate) que pueda señalar como un posible problema . Desafortunadamente, si eso resulta ser el problema real (lo cual no me sorprendería mucho), todo podría estar arruinado, y terminaré reescribiéndolos en SQL simple. Espero que sea un problema de recolector de basura o algo más fácil de tratar que NHibernate.
@Joshdan: No secret. Como dije, probamos todos los problemas habituales. La creación de perfiles no fue útil: el generador de perfiles que utilizamos no pudo señalar ningún código que se estaba ejecutando cuando el uso de la CPU era alto. Estos servicios fueron destrozados hace aproximadamente un mes buscando este problema. Cada sección del código fue analizada para tratar de averiguar si nuestro código era el problema; No estoy aquí preguntando porque no he hecho mi tarea. Si este fuera un caso simple de los servicios haciendo más trabajo de lo previsto, eso es algo que habría sido atrapado.
El problema aquí es que, la mayoría de las veces, los servicios no están haciendo nada en absoluto, y aún logran consumir el 25% o más de cuatro núcleos de CPU: no encuentran trabajo que hacer, y salir de su bucle y esperando la siguiente iteración. Esto debería, literalmente, tomar casi ningún tiempo de CPU en absoluto.
Aquí hay un ejemplo de comportamiento que estamos viendo, en un servicio sin trabajo durante dos días (en un entorno inmutable). Esto fue capturado la semana pasada:
Día 1, 8AM: Prom. Uso de CPU aproximadamente 3%
Día 1, 6 PM: Prom. Uso de CPU aproximadamente 8%
Día 2, 7AM: Prom. Uso de la CPU aproximadamente 20%
Día 2, 11AM: Prom. Uso de la CPU aproximadamente 30%
Después de haber analizado todas las posibles razones mundanas para esto, hice esta pregunta aquí porque pensé (con razón, resulta que) que obtendría respuestas más innovadoras (como Ubiguchi's), o punteros a cosas que yo no había pensado en (como la sugerencia de Ian).
Así ocurre el pico de la CPU inmediatamente anterior a la devolución de llamada temporizador , dentro de la devolución de llamada de temporizador, o inmediatamente después de que el temporizador devolución de llamada?
Lo malinterpreta. Esto no es un aumento. Si lo fuera, no habría ningún problema; Puedo lidiar con los picos. Pero no es ... el uso de la CPU está aumentando en general. Incluso cuando el servicio no está haciendo nada, esperando el próximo golpe de temporizador. Cuando se inicia el servicio, las cosas son agradables y tranquilas, y el gráfico se ve como lo que se espera ... generalmente, 0% de uso, con picos al 10% cuando NHibernate llega a la base de datos o el servicio realiza una cantidad de trabajo trivial . Pero esto aumenta a un uso general del 25% (más si lo dejo ir demasiado lejos) en todo momento mientras el proceso se está ejecutando.
Eso hizo que la sugerencia de Ian fuera la bala de plata lógica (NHibernate hace muchas cosas cuando no estás buscando). Por desgracia, he implementado su solución, pero no ha tenido ningún efecto (no tengo pruebas de esto, pero en realidad creo que empeoró las cosas ... el uso promedio es aparentando que sube mucho más rápido ahora).Tenga en cuenta que eliminar las "secciones" de NHibernate (como usted recomienda) no es factible, ya que eso eliminaría aproximadamente el 90% del código en el servicio, lo que me permitiría descartar el temporizador como un problema (que tengo la absoluta intención de intente), pero no puede ayudarme a descartar NHibernate como el problema, porque si NHibernate está causando esto, entonces la solución dudosa que se implementó (ver a continuación) simplemente tendrá que convertirse en The Way The System Works; dependemos tanto de NHibernate para este proyecto que el PM simplemente no aceptará que está causando un problema estructural irresolubles.
acabo de señalar un sentido de desesperación en la pregunta - que sus problemas continuarían salvo un pequeño milagro
no me refiero a que venga de esa manera. Por el momento, los servicios se reinician a diario (con la opción de ingresar cualquier cantidad de horas del día para que se apaguen y reinicien), lo que soluciona el problema pero no puede ser una solución a largo plazo una vez que ingresan en la máquina de producción. y comienza a estar ocupado Los problemas no continuarán, ya sea que los solucione o el PM mantiene esta restricción sobre ellos. Obviamente, preferiría implementar una solución real, pero dado que las pruebas iniciales no revelaron ninguna razón para esto, y los servicios ya han sido ampliamente revisados, el PM prefiere simplemente reiniciarlos varias veces antes de pasar más tiempo tratando de arreglarlos. . Eso está completamente fuera de mi control y hace que el milagro del que hablas sea más importante de lo que sería de otra manera.
Eso es extremadamente intrigante (en cuanto a ya que confía en su generador de perfiles).
I do not. Pero entonces, estos son servicios de Windows escritos en .NET 1.1 que se ejecuta en una máquina con Windows 2000, implementados por una secuencia de comandos Nant poco fiable, utilizando una versión anterior de NHibernate para el acceso a la base de datos. Hay poco en esa máquina en la que realmente diría que confío.
¿Es posible que su temporizador de servicio esté activo más de lo necesario? Digamos, el temporizador se activa y el ciclo no se ejecuta aún, y pasan 2 minutos. ¿Se activará el temporizador nuevamente? Muchas cosas pueden salir mal, pero todas están relacionadas específicamente con tu código. Este no es el comportamiento normal de un servicio. – Jaywalker
¿Tiene algún código que detecte si el servicio todavía está "funcionando" en un ciclo de trabajo anterior? – hova