2010-10-06 6 views
4

J'utilise RabbitMQ et j'essaie de refactoriser ma mise en œuvre java native actuelle à l'aide de l'abstraction Spring AMQP.Déclaration des échanges et des files d'attente au printemps AMQP

La déclaration des échanges, des files d'attente et de leur liaison à l'aide de la bibliothèque Spring se fait via l'interface AMQPAdmin, mais je ne suis pas sûr quand ce type de configuration devrait se produire.

J'ai une application web qui utilise Rabbit pour produire des messages. Et une autre application qui consomme ces messages. Shocker :)

Mais quand afficher la déclaration des échanges/files d'attente ont lieu? Dois-je déployer AMQPAdmin avec les applications Web et gérer l'échange/la file d'attente au sein des constructeurs de producteurs et de consommateurs?

La déclaration de ces choses est un one-off, le cassé n'a pas besoin de savoir à leur sujet à nouveau, donc tout code serait un NOOP sur les exécutions suivantes. Est-ce que je crée une application séparée pour l'administration du courtier?

Quelle est la pensée actuelle ou les meilleures pratiques ici?

Répondre

6

Il semblerait que très peu de gens utilisent la version AMQP M1 de Spring, alors je vais répondre à ma propre question avec ce que j'ai fait.

Dans le constructeur du producteur, je déclare l'échange. Ensuite, définissez l'échange sur le RabbitTemplate. J'ai également défini la clé de routage sur le RabbitTemplate comme le nom de la file d'attente, mais ce n'est pas obligatoire, mais c'était la route que j'utiliserais.

@Service("userService") 
public class UserService { 
    private final RabbitTemplate rabbitTemplate; 

    @Autowired 
    public UserService(final RabbitAdmin rabbitAdmin, 
         final Exchange exchange, 
         final Queue queue, 
         @Qualifier("appRabbitTemplate") final RabbitTemplate rabbitTemplate) { 

     this.rabbitTemplate = rabbitTemplate; 

     rabbitAdmin.declareExchange(exchange); 
     rabbitTemplate.setExchange(exchange.getName()); 
     rabbitTemplate.setRoutingKey(queue.getName()); 
    } 


    public void createAccount(final UserAccount userAccount) { 
     rabbitTemplate.convertAndSend("Hello message sent at " + new DateTime()); 
    } 
} 

Dans le constructeur du consommateur, je déclare la file d'attente et crée la liaison.

public class Consumer implements ChannelAwareMessageListener<Message> { 

    public Consumer(final RabbitAdmin rabbitAdmin, final Exchange exchange, final Queue queue) { 
     rabbitAdmin.declareQueue(queue); 

     rabbitAdmin.declareBinding(BindingBuilder.from(queue).to((DirectExchange) exchange).withQueueName()); 
    } 

    @Override 
    public void onMessage(Message message, Channel channel) throws Exception { 

     System.out.println(new String(message.getBody())); 

     channel.basicAck(message.getMessageProperties().getDeliveryTag(), true); 
    } 
} 

Bien que les constructeurs peuvent être exécutés à plusieurs reprises, RabbitMQ déclare que l'échange, la file d'attente et les liaisons une fois.

Si vous avez besoin de toute la source pour ce petit exemple de projet, demandez, et je l'installerai quelque part pour vous.

+0

Veuillez faire! J'aimerais voir comment vous avez tout fait pendant que je me bats avec ça maintenant. –

+0

@dom farr, dans [Spring Messaging pour RabbitMQ] (https://spring.io/guides/gs/messaging-rabbitmq/), 'rabbitTemplate',' queue', 'exchange' et' binding' sont tous configurés par Spring Boot. Ce que je ne comprends pas, c'est comment 'rabbitTemplate.convertAndSend (...)' l'envoie à l'échange créé, car l'appel de méthode ne spécifie aucun échange et seulement la clé de routage (via le nom de la file) - ce que je pensais implicitement envoie à l'échange par défaut et non l'échange créé. –

+0

@WebUser En regardant rapidement la documentation, vous pouvez voir que les beans définis pour l'échange, la file d'attente et la liaison dans le fichier de configuration. Ensuite, Spring Boot crée le RabbitTemplate, il utilisera ces beans. –

Questions connexes