Exchange服务器之一张图带你理解和实现RabbitMQ的延迟队列功能
白羽 2018-07-26 来源 :网络 阅读 1828 评论 0

摘要:本文将带你了解Exchange服务器之一张图带你理解和实现RabbitMQ的延迟队列功能,希望本文对大家学Exchange有所帮助

开头

先熟悉下面会用到的一些名词~


exchange: 交换机
routingkey: 路由key
queue: 队列


exchange和queue是需要绑定在一起的,然后消息发送到exchange再由exchange通过routingkey发送到对应的队列中。



(不是这张图~~~)

exchange分四种



Default Exchange

这种是特殊的Direct Exchange,是rabbitmq内部默认的一个交换机。该交换机的name是空字符串,所有queue都默认binding 到该交换机上。所有binding到该交换机上的queue,routing-key都和queue的name一样。

注意: 这就是为什么你直接创建一个queue也能正常的生产与消费,因为对应的exchange是RabbitMQ默认的,routingkey就是该队列的名字



Topic Exchange

通配符交换机,exchange会把消息发送到一个或者多个满足通配符规则的routing-key的queue。其中表号匹配一个word,#匹配多个word和路径,路径之间通过.隔开。如满足a..c的routing-key有a.hello.c;满足#.hello的routing-key有a.b.c.helo。



Fanout Exchange

扇形交换机,该交换机会把消息发送到所有binding到该交换机上的queue。这种是publisher/subcribe模式。用来做广播最好。 
所有该exchagne上指定的routing-key都会被ignore掉。



Header Exchange

设置header attribute参数类型的交换机。

简单的了解之后,下面就是延迟队列的实现方式



延迟队列的实现

延迟分两种


在msg上设置过期时间
在队列上设置过期时间


一定要看懂这张图!!! 


如上图创建三个exchange和三个队列



@Bean
public DirectExchange delayExchange() {
    return new DirectExchange(DELAY_EXCHANGE_NAME);
}

@Bean
public DirectExchange processExchange() {
    return new DirectExchange(PROCESS_EXCHANGE_NAME);
}

@Bean
public DirectExchange delayQueueExchange() {
    return new DirectExchange(DELAY_QUEUE_EXCHANGE_NAME);
}

/**
 * 存放延迟消息的队列 最后将会转发给exchange(实际消费队列对应的)
 * @return
 */
@Bean
Queue delayQueue4Msg(){
    return QueueBuilder.durable(DELAY_QUEUE_MSG)
            .withArgument("x-dead-letter-exchange", PROCESS_EXCHANGE_NAME) 
            .withArgument("x-dead-letter-routing-key", ROUTING_KEY) 
            .build();
}

@Bean
public Queue processQueue() {
    return QueueBuilder.durable(PROCESS_QUEUE)
            .build();
}

/**
 * 存放消息的延迟队列 最后将会转发给exchange(实际消费队列对应的)
 * @return
 */
@Bean
public Queue delayQueue4Queue() {
    return QueueBuilder.durable(DELAY_QUEUE_NAME)
            .withArgument("x-dead-letter-exchange", PROCESS_EXCHANGE_NAME) // DLX
            .withArgument("x-dead-letter-routing-key", ROUTING_KEY) 
            .withArgument("x-message-ttl", 3000) // 设置队列的过期时间 单位毫秒
            .build();
}
接下来将每个exchange和对应的mq绑定



@Bean
Binding delayBinding() {
    return BindingBuilder.bind(delayQueue4Msg())
            .to(delayExchange())
            .with(ROUTING_KEY);
}

@Bean
Binding queueBinding() {
    return BindingBuilder.bind(processQueue())
            .to(processExchange())
            .with(ROUTING_KEY);
}
@Bean
Binding delayQueueBind() {
    return BindingBuilder.bind(delayQueue4Queue())
            .to(delayQueueExchange())
            .with(ROUTING_KEY);
}

发送消息的方式



public void sendDelayMsg(Msg msg) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println(msg.getId() + " 延迟消息发送时间:" + sdf.format(new Date()));
    rabbitTemplate.convertAndSend(RabbitConfig.DELAY_EXCHANGE_NAME, "delay", msg, new MessagePostProcessor() {
        @Override
        public Message postProcessMessage(Message message) throws AmqpException {
            message.getMessageProperties().setExpiration(msg.getTtl() + "");
            return message;
        }
    });
}

public void sendDelayQueue(Msg msg) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println(msg.getId() + " 延迟队列消息发送时间:" + sdf.format(new Date()));
    rabbitTemplate.convertAndSend(RabbitConfig.DELAY_QUEUE_EXCHANGE_NAME,"delay",  msg);
}


验证结果

为每个消息设置过期时间 


为队列设置过期时间 


如果你把设置了过期时间的消息发送到设置了过期时间的队里中的时候,以最短的时间为准~~



最后

其实我在实现的过程中也花了很长的时间,主要就是被exchange和queue搞乱掉了,最后索性自己画了个图,按照图来一个一个创建与绑定。之后就很清晰很容易的实现了。


  强调!!! 如果在开发的过程中发现exchange和queue绑定错误了,建议从管理界面将queue和exchange unbind或者删除重新创建!
   

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标系统运维之Exchange频道!

本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 1
看完这篇文章有何感觉?已经有2人表态,50%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程