RabbitMQ常用模式

一. RabbitMQ架构分析

 

 

一、订阅模式(Fanout Exchange)

一个生产者,多个消费者,每一个消费者都有自己的一个队列,生产者没有将消息直接发送到队列,而是发送到了交换机,每个队列绑定交换机,生产者发送的消息经过交换机,到达队列,实现一个消息被多个消费者获取的目的。需要注意的是,如果将消息发送到一个没有队列绑定的exchange上面,那么该消息将会丢失,这是因为在rabbitMQ中exchange不具备存储消息的能力,只有队列具备存储消息的能力,类似子网广播,交换机,以广播的形式,不处理路由键,将消息发送到每个绑定的队列,Fanout Exchange 转发消息是最快的。

spring boot 示例代码:

 配置交换机绑定队列

@Configuration
public class RabbitConfig {

    @Bean
    FanoutExchange addfanoutExchange() {
        return new FanoutExchange(Constants.RABBIT_DATAMAP);
    }

    @Bean
    public Queue imageHouseMessage(){
        return new Queue(Constants.RABBIT_DATAMAP+".imageHouse");
    }
    @Bean
    public Queue normalHouseMessage(){
        return new Queue(Constants.RABBIT_DATAMAP+".normalHouse");
    }
    @Bean
    Binding bindingExchangeAddimageHouseMessage(Queue imageHouseMessage, FanoutExchange addfanoutExchange) {
        return BindingBuilder.bind(imageHouseMessage).to(addfanoutExchange);
    }
    @Bean
    Binding bindingExchangeAddnormalHouseMessage(Queue normalHouseMessage, FanoutExchange addfanoutExchange) {
        return BindingBuilder.bind(normalHouseMessage).to(addfanoutExchange);
    }
    
}

生产者

@Component
public class RabbitProductorTemplate {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    public void publish(){
        rabbitTemplate.convertAndSend(Constants.RABBIT_DATAMAP, "", new HashMap<>());
    }
}

消费者

@RabbitListener(queues ="startspush_dataMap.normalHouse")
public class RabbitSubscribeTemplate {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @RabbitHandler
    private void process(Map<String,Object> dataMap){
        
    }
}

二、路由模式(Direct Exchange)

这种模式添加了一个路由键,生产者发布消息的时候添加路由键,消费者绑定队列到交换机时添加键值,这样就可以接收到需要接收的消息,路由交换机根据路由键精确匹配绑定键然后投递到绑定队列中,允许多绑定方式,拥有扇形交换机的能力同时支持精确路由。

       

@Configuration
public class RabbitConfig {

    @Bean
    FanoutExchange addfanoutExchange() {
        return new FanoutExchange(Constants.RABBIT_DATAMAP);
    }

    @Bean
    public Queue imageHouseMessage(){
        return new Queue(Constants.RABBIT_DATAMAP+".imageHouse");
    }
    @Bean
    public Queue normalHouseMessage(){
        return new Queue(Constants.RABBIT_DATAMAP+".normalHouse");
    }
    @Bean
    Binding bindingExchangeAddimageHouseMessage(Queue imageHouseMessage, FanoutExchange addfanoutExchange) {
        return BindingBuilder.bind(imageHouseMessage).to(addfanoutExchange);
    }
    @Bean
    Binding bindingExchangeAddnormalHouseMessage(Queue normalHouseMessage, FanoutExchange addfanoutExchange) {
        return BindingBuilder.bind(normalHouseMessage).to(addfanoutExchange);
    }

}

生产者根据路由Key交换机转发不同队列。

@Component
public class RabbitProductorTemplate {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    public void publish(){
        rabbitTemplate.convertAndSend(Constants.RABBIT_DATAMAP, "normal", new HashMap<>());
        rabbitTemplate.convertAndSend(Constants.RABBIT_DATAMAP, "image", new HashMap<>()); 
    }
}

 监听消费normal队列

@RabbitListener(queues ="startspush_dataMap.normalHouse")
public class RabbitSubscribeTemplate {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @RabbitHandler
    private void process(Map<String,Object> dataMap){

    }
}

监听消费image队列

@RabbitListener(queues ="startspush_dataMap.imageHouse") public class RabbitSubscribeTemplate { @Autowired private RabbitTemplate rabbitTemplate; @RabbitHandler private void process(Map<String,Object> dataMap){ } }

  二、主题交换机(Topic Exchange)  

发送到主题交换机(topic exchange)的消息不可以携带随意什么样子的路由键(routing_key),它的路由键必须是一个由.分隔开的词语列表。这些单词随便是什么都可以,但是最好是跟携带它们的消息有关系的词汇。以下是几个推荐的例子:"stock.usd.nyse", "nyse.vmw", "quick.orange.rabbit"。词语的个数可以随意,但是不要超过255字节。

绑定键也必须拥有同样的格式。主题交换机背后的逻辑跟直连交换机很相似 —— 一个携带着特定路由键的消息会被主题交换机投递给绑定键与之想匹配的队列。但是它的绑定键和路由键有两个特殊应用方式:

  • * (星号) 用来表示一个单词.
  • # (井号) 用来表示任意数量(零个或多个)单词。

None

主题交换机是很强大的,它可以表现出跟其他交换机类似的行为

当一个队列的绑定键为 "#"(井号) 的时候,这个队列将会无视消息的路由键,接收所有的消息。

当 * (星号) 和 # (井号) 这两个特殊字符都未在绑定键中出现的时候,此时主题交换机就拥有的直连交换机的行为。

@Configuration
public class RabbitTopicConfig {

    @Bean
    TopicExchange addTopicExchange() {
        return new TopicExchange(Constants.RABBIT_DATAMAP);
    }

    @Bean
    public Queue imageHouseMessage() {
        return new Queue(Constants.RABBIT_DATAMAP + ".imageHouse");
    }

    @Bean
    public Queue normalHouseMessage() {
        return new Queue(Constants.RABBIT_DATAMAP + ".normalHouse");
    }

    @Bean
    Binding bindingExchangeAddimageHouseMessage(Queue imageHouseMessage, TopicExchange addTopicExchange) {
        return BindingBuilder.bind(imageHouseMessage).to(addTopicExchange).with("*.orange.*");
    }

    @Bean
    Binding bindingExchangeAddnormalHouseMessage(Queue normalHouseMessage, TopicExchange addTopicExchange) {
        return BindingBuilder.bind(normalHouseMessage).to(addTopicExchange).with("*.*.rabbit*,*.orange.*");
    }

}

生产者根据路由不同队列。

@Component
public class RabbitProductorTemplate {
@Autowired
private RabbitTemplate rabbitTemplate;
public void publish(){
rabbitTemplate.convertAndSend(Constants.RABBIT_DATAMAP, "
*.*.rabbit*,*.orange.*,*.orange.*", new HashMap<>());
}
}

 

 监听消费normal队列

@RabbitListener(queues ="startspush_dataMap.normalHouse")
public class RabbitSubscribeTemplate {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @RabbitHandler
    private void process(Map<String,Object> dataMap){

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值