2010-11-25 5 views
5

J'utilise ActiveMQ dans un programme .Net et je suis inondé d'événements-messages. En bref, quand j'obtiens un événement de file d'attente 'onMessage (IMessage receivedMsg)' je place le message dans une file d'attente interne à partir de laquelle les threads X font leur chose. Au début, j'ai eu: 'AcknowledgementMode.AutoAcknowledge' lors de la création de la session, donc je devine que tous les messages dans la file d'attente ont été aspirés et mis dans la file d'attente de mémoire (ce qui est risqué car tout est perdu). Alors j'ai utilisé: 'AcknowledgementMode.ClientAcknowledge' lors de la création de la session, et quand un worker était prêt avec le message, il appelle la méthode 'commit()' sur le message. Cependant, tous les messages sont toujours aspirés par la file d'attente.Comment puis-je limiter la quantité de messages provenant d'ActiveMQ dans mon application C#?

Comment puis-je le configurer que SEULEMENT un nombre X de messages sont en cours de traitement ou sont dans une file d'attente interne, et que tout n'est pas «téléchargé» tout de suite?

+0

Bien que je n'ai jamais touché ActiveMQ - ne pouvez-vous pas retourner ceci: Configurer N threads avec les écouteurs ActiveMQ, et traiter les messages dans l'événement listen? –

+0

@will hughes: mon programme entier est écrit de manière asynchrone. Ainsi, même l'accès DB est effectué de manière asynchrone avec des rappels. Donc je ne peux pas rester dans l'événement. – Toad

Répondre

3

Êtes-vous sur .NET 4.0? Vous pouvez utiliser un BlockingCollection. Réglez-le à la quantité maximale qu'il peut contenir. Dès qu'un thread essaie de placer un élément en excès, l'opération d'ajout est bloquée jusqu'à ce que la collection revienne au-dessous du seuil.

Peut-être que cela le ferait pour étrangler?

Il existe également une API pour la limitation dans le framework Rx, mais je ne sais pas comment elle est implémentée. Si vous implémentez votre source de file d'attente comme Observable, cette API deviendra disponible pour vous, mais je ne sais pas si cela répond à vos besoins.

+0

bonne réponse! Fonctionne comme un charme. Merci – Toad

2

Vous pouvez définir le prefetch client pour contrôler le nombre de messages que le client sera envoyé. Lorsque la session est en réception automatique, le client n'acceptera un message qu'une fois qu'il a été remis à votre application via le rappel onMessage ou via une réception synchrone. Par défaut, le client prélèvera 1000 messages du courtier, si le client tombe en panne, ces messages seront redistribués à un autre client s'il s'agissait d'une file d'attente, sinon pour un sujet, ils sont simplement supprimés car un sujet est un canal basé sur la diffusion. Si vous définissez la prélecture à un, votre client ne recevra qu'un seul message du serveur, puis chaque fois que votre rappel onMessage sera terminé, un nouveau message sera distribué car le client accèdera à ce message, c'est-à-dire si la session est dans Auto Ack mode.

Reportez-vous à la page de configuration NMS pour toutes les options: http://activemq.apache.org/nms/configuring.html

Cordialement

Tim. FuseSource.com

+0

bish: Malheureusement, même si je mets à clientacknowledge, la file d'attente déclenchera autant d'événements qu'il y a de messages dans la file d'attente. Je l'ai testé avec 10.000 messqges dans la file d'attente et ils seront virés sans que je reconnaisse quoi que ce soit. La seule façon de l'arrêter est d'arrêter l'onMessage jusqu'à ce que je l'ai traité. – Toad

+0

Sons comme votre modèle de programmation serait mieux adapté par l'utilisation des appels de réception synchrones, alors vous pouvez étrangler tout ce que vous aimez. Le but du système de messagerie est de livrer les messages aussi vite que possible, votre application doit faire face à la limitation. –

Questions connexes