Pregunta

He de crear un servicio WCF y estoy utilizando netMsmqBinding de unión.

Este es un sencillo servicio que pases un Dto a mi método de servicio y no esperar una respuesta.El mensaje se coloca en un MSMQ, y una vez recogido se inserta en una base de datos.

¿Cuál es el mejor método para asegurarse de que los datos no se pierden.

He probado los 2 métodos siguientes:

  1. Lanzar una excepción

    Esto coloca el mensaje en la letra muerta de la cola para el manual de lectura.Puedo proceso de esto cuando mi strvice comienza

  2. establecer el receiveRetryCount="3" en la unión

    Después de 3 intentos - que sucede instantanously, esto parece dejar el mensaje en la cola, pero la culpa de mi servicio.Reiniciar mi servicio repite este proceso.

Idealmente me gustaría hacer las siguientes:

Intenta procesar el mensaje

  • Si esto falla, espere 5 minutos para que el mensaje y vuelva a intentarlo.
  • Si el proceso falla 3 veces, mover el mensaje a una cola de entrega.
  • Reiniciar el servicio de push todos los mensajes de la letra muerta de la cola de nuevo en la cola de modo que pueda ser procesado.

Puedo lograr esto?Si es así, cómo?Puede que me apunte a cualquier buenos artículos sobre cómo mejor utilizar WCF y MSMQ para mi dado sceneria.

Cualquier ayuda sería muy apreciada.Gracias!

Alguna información adicional

Estoy usando MSMQ 3.0 en Windows XP y Windows Server 2003.Lamentablemente yo no puedo utilizar el construido en el veneno mensaje de apoyo dirigidos a MSMQ 4.0 y Vista/2008.

¿Fue útil?

Solución

Hay un ejemplo en el SDK que podría ser útil en su caso.Básicamente, lo que hace es conectar un IErrorHandler aplicación a su servicio que se captura el error cuando WCF declara el mensaje de "veneno" (es decir,cuando todos los intentos configurados se han agotado).Lo que la muestra no es mover el mensaje a otra cola y, a continuación, reinicie el ServiceHost asociado con el mensaje (ya que se tienen un fallo cuando el veneno mensaje fue encontrado).

No es una muy bonita de la muestra, pero puede ser útil.Hay un par de limitaciones, a pesar de que:

1 - Si usted tiene múltiples extremos asociados con el servicio (es decir,se exponen a través de varias colas), no hay ninguna manera de saber que la cola de la cola de mensajes de llegar.Si sólo tiene una sola cola, esto no será un problema.No he visto ningún oficial solución para esto, pero he experimentado con una posible alternativa que he documentado aquí: http://winterdom.com/weblog/2008/05/27/NetMSMQAndPoisonMessages.aspx

2 - una Vez que el mensaje del problema se traslada a otro de la cola, que se convierte en su responsabilidad, por lo que depende de usted para llevarlo de nuevo a la cola de procesamiento una vez que el tiempo de espera se hace (o adjunte un nuevo servicio a la cola para manejar).

Para ser honesto, en cualquier caso, usted está buscando en algún "manual" trabajo aquí, WCF no cubre en su propio.

He estado recientemente trabajando en un proyecto diferente, donde tengo un requisito para controlar de forma explícita cómo a menudo el número de reintentos de suceder, y mi solución fue la creación de un conjunto de colas de reintento y mover manualmente los mensajes entre las colas de reintento de los principales cola de procesamiento basado en un conjunto de temporizadores y algunas heurísticas, simplemente utilizando el Sistema de primas.Mensajería cosas para manejar las colas MSMQ.Parece que funciona bastante bien, aunque hay un par de errores si ir por este camino.

Otros consejos

Creo que con MSMQ (disponible sólo en windows Vista), usted podría ser capaz de hacer como esto:

<bindings>
    <netMsmqBinding>
        <binding name="PosionMessageHandling"
             receiveRetryCount="3"
             retryCycleDelay="00:05:00"
             maxRetryCycles="3"
             receiveErrorHandling="Move" />
    </netMsmqBinding>
</bindings>

WCF inmediatamente reintentar para ReceiveRetryCount veces después de la primera llamada al fracaso.Después de que el lote ha fallado el mensaje se mueve a la cola de reintento.Después de un retraso de RetryCycleDelay minutos, el mensaje se trasladó de la cola de reintento para el extremo de la cola y el lote se vuelve a intentar.Esto se repetirá MaxRetryCycle tiempo.Si todo eso falla, el mensaje es manejado de acuerdo a receiveErrorHandling que se puede mover (a la cola de daños), rechazar, caída o fallo

Por la forma en que un buen texto sobre WCF y MSMQ es el chapther 9 de Progammig WCF libro de Juval Lowy

Si está utilizando SQL-Server, a continuación, usted debe utilizar una transacción distribuida, ya que ambos MSMQ y SQL-Server de apoyo.Lo que pasa es que envuelva a su base de datos de escribir en un bloque TransactionScope y llame a su alcance.Completa() sólo si se ejecuta correctamente.Si esto falla, entonces cuando su WCF método devuelve el mensaje será colocado de nuevo en la cola para ser juzgado de nuevo.He aquí una versión recortada de código que utilizo:

    [OperationBehavior(TransactionScopeRequired=true, TransactionAutoComplete=true)]
    public void InsertRecord(RecordType record)
    {
        try
        {
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
            {
                SqlConnection InsertConnection = new SqlConnection(ConnectionString);
                InsertConnection.Open();

                // Insert statements go here

                InsertConnection.Close();

                // Vote to commit the transaction if there were no failures
                scope.Complete();
            }
        }
        catch (Exception ex)
        {
            logger.WarnException(string.Format("Distributed transaction failure for {0}", 
                Transaction.Current.TransactionInformation.DistributedIdentifier.ToString()),
                ex);
        }
     }

Puedo probar esto por la formación de colas de hasta un gran número de registros, vamos a WCF inicio de un montón de hilos para manejar muchos de ellos de forma simultánea (alcanza los 16 hilos--16 mensajes de la cola a la vez), luego de matar el proceso en el centro de operaciones.Cuando se reinicie el programa se leen los mensajes de atrás de la cola y lo procesa de nuevo como si nada hubiera pasado, y en la conclusión de la prueba de la base de datos es coherente y no tiene registros que faltan.

Distributed Transaction Manager tiene un ambiente de presencia, y cuando se crea una nueva instancia de TransactionScope se busca automáticamente la transacción actual en el ámbito de aplicación del método de la llamada, lo que ya han sido creados por la WCF cuando apareció el mensaje de la cola y se invoca el método.

Por desgracia estoy atascado en Windows XP y Windows Server 2003, por lo que no es una opción para mí.- (Tengo que volver a aclarar que en mi pregunta de como encontré esta solución después de la publicación y se dio cuenta de que no podía utilizarlo)

He encontrado que una de las soluciones fue la instalación de un controlador personalizado que iba a cambiar mi mensaje en otro de la cola o la cola de daños y reiniciar el servicio.Esto parecía una locura para mí.Imaginen mi Sql Server estaba abajo con qué frecuencia el servicio podría ser reiniciado.

ASÍ que lo que he terminado haciendo es permitiendo que la Línea de falla y dejar mensajes en la cola.Yo también registro un fatal mensaje a mi sistema de servicio de registro de que esto ha sucedido.Una vez que nuestro problema está resuelto, me reinicie el servicio y todos los mensajes de empezar a procesar de nuevo.

Me di cuenta de re-procesamiento de este mensaje o de cualquier otro no todos, así que ¿por qué la necesidad de mover este mensaje y los otros a la otra cola.Me pueden dejar mi servicio, y se comienza de nuevo cuando todo está funcionando como se esperaba.

aogan, tenía la respuesta perfecta para MSMQ 4.0, pero por desgracia no es para mí

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