Mi pregunta original de hace un tiempo es MSMQ Slow Queue Reading, sin embargo, he avanzado desde eso y ahora creo que sé que el problema es un poco más claro.MSMQ Receive() método de tiempo de espera
Mi código (bueno en realidad parte de una biblioteca de código abierto que estoy usando) tiene el siguiente aspecto:
queue.Receive(TimeSpan.FromSeconds(10), MessageQueueTransactionType.Automatic);
que está utilizando la función Messaging.MessageQueue.Receive y la cola es una MessageQueue. El problema es el siguiente.
Se invocará la línea de código anterior con el tiempo de espera especificado (10 segundos). La función Receive(...)
es una función de bloqueo, y se supone que debe bloquear hasta que llegue un mensaje en la cola y en ese momento volverá. Si no se recibe ningún mensaje antes de que se agote el tiempo de espera, volverá en el tiempo de espera. Si un mensaje está en la cola cuando se llama a la función, devolverá ese mensaje inmediatamente.
Sin embargo, lo que está sucediendo es que se está llamando a la función Receive(...)
, viendo que no hay ningún mensaje en la cola y esperando que entre un nuevo mensaje. Cuando ingresa un nuevo mensaje (antes del tiempo de espera), no está detectando este nuevo mensaje y continúa esperando. El tiempo de espera finalmente se alcanza, en cuyo punto el código continúa y llama al Receive(...)
nuevamente, donde recoge el mensaje y lo procesa.
Ahora, este problema solo ocurre después de un número de días/semanas. Puedo hacer que funcione normalmente de nuevo eliminando & recreando la cola. Sucede en diferentes computadoras y diferentes colas. Por lo tanto, parece que algo se está acumulando, hasta cierto punto cuando se rompe la capacidad de activación/notificación que utiliza la función Receive(...)
.
He comprobado muchas cosas diferentes, y todo parece normal & no es diferente de una cola que funciona normalmente. Hay un montón de espacio en disco (13 gig gratis) y RAM (alrededor de 350 MB sin 1 GB de lo que puedo decir). He revisado las entradas de registro, que parecen todas iguales a las otras colas, y el monitor de rendimiento no muestra nada fuera de lo normal. También he ejecutado la herramienta TMQ y no puedo ver nada notoriamente erróneo a partir de eso.
Estoy usando Windows XP en todas las máquinas y todas tienen Service Pack 3 instalado. No estoy enviando una gran cantidad de mensajes a las colas, a lo sumo sería 1 cada 2 segundos, pero en general mucho menos frecuentes que eso. Los mensajes son pequeños también y no están cerca del límite de 4MB.
Lo único que acabo de notar es que los archivos p0000001.mq y r0000067.mq en C: \ WINDOWS \ system32 \ msmq \ storage son ambos 4.096KB pero también tienen ese tamaño en otras computadoras que no están experimentando actualmente el problema. El problema no le ocurre a todas las colas en la computadora a la vez, ya que puedo recrear 1 cola de problemas en la computadora y las otras colas todavía experimentan el problema.
No tengo mucha experiencia con MSMQ así que si publica cosas posibles para verificar, puede explicar cómo verificarlas o dónde puedo encontrar más detalles de lo que está hablando.
Actualmente la situación es:
- EquipoA - 4 colas normales
- ComputerB - 2 colas que experimentan problema, 1 cola normal de
- ComputerC - 2 colas que experimentan problema
- SistemaD - 1 cola normal de
- ComputerE - 2 colas normal
Así que tengo una gran cantidad de computadoras/colas para comparar y contrastar.
Lo que utiliza la biblioteca de código abierto? ¿Es un problema conocido de su parte? –
Es NServiceBus (www.nservicebus.com). No parece que nadie más experimente el problema (al menos nadie en la lista de correo). Mi explicación de cómo funciona se basa en cómo lo describe el propietario. "Un subproceso de NServiceBus busca en la cola un mensaje después de que termina de procesar el mensaje anterior (o al inicio). El comportamiento habitual de un vistazo es bloquear hasta que llega un mensaje, pero NServiceBus limita esto con un tiempo de espera para permitir el apagado correcto en cualquier punto del tiempo ". Y la línea de código que pegué es el mencionado 'vistazo'. – mike
Bueno, no soy un experto en el campo, pero estoy mirando la cola. Espero que el segundo parámetro no sea el más adecuado en su caso, tal vez cambiando a "MessageQueueTransactionType.None" (si no necesita la función de transacción) seria mejor. La segunda forma de eludir esto (en mi opinión) sería mover la función de tiempo de espera fuera de esta llamada, lo que significa que en esta llamada solo espere 0 segundos y espere en otro lugar de su código. Entiendo que estas opciones pueden no ser ideales ya que es posible que deba cambiar el contenido de la biblioteca o su código. buena suerte –