当前位置: 首页 > news >正文

建网站首选公司新闻媒体发稿平台

建网站首选公司,新闻媒体发稿平台,成都网站建设服务有什么,网站网上商城建设(一)延迟队列 1.概念 延迟队列是一种特殊的队列,消息被发送后,消费者并不会立刻拿到消息,而是等待一段时间后,消费者才可以从这个队列中拿到消息进行消费 2.应用场景 延迟队列的应用场景很多,…

(一)延迟队列

1.概念

 延迟队列是一种特殊的队列,消息被发送后,消费者并不会立刻拿到消息,而是等待一段时间后,消费者才可以从这个队列中拿到消息进行消费

2.应用场景

 延迟队列的应用场景很多,就比如大部分定时的场景,我们都可以利用延迟队列例如:闹钟定时,预约会议,空调定时开关等

 但是RabbitMQ是没有直接给我们提供延迟队列的,但是我们可以通过上一篇博客说的ttl和死信来达到延迟队列的效果,具体操作如下

 首先我们有一个交换机和一个队列,然后此队列又指定一个死信交换机,死信交换机绑定一个死信队列,然后我们消费者并不是从正常队列中获取消息,而是从死信队列中获取消息,通过给消息/队列设置过期时间来影响消息到达死信队列的时间,消费者拿到消息就会延迟,这样就可以模拟出延迟的效果。

那接下来就是我们的代码实现

首先我们通过设置队列ttl来实现

 @Bean("ttlExchange")public Exchange ttlExchange(){return ExchangeBuilder.directExchange(Constants.TTL_EXCHANGE).durable(true).build();}@Bean("ttlQueue")public Queue ttlQueue(){return QueueBuilder.durable(Constants.TTL_QUEUE).ttl(5000).deadLetterExchange(Constants.DEAD_EXCHANGE).deadLetterRoutingKey("dead").build();}@Bean("ttlBind")public Binding ttlBind(@Qualifier("ttlExchange") Exchange ackExchange,@Qualifier("ttlQueue") Queue queue){return BindingBuilder.bind(queue).to(ackExchange).with("ttl").noargs();}@Bean("deadExchange")public Exchange deadExchange(){return ExchangeBuilder.directExchange(Constants.DEAD_EXCHANGE).durable(true).build();}@Bean("deadQueue")public Queue deadQueue(){return QueueBuilder.durable(Constants.DEAD_QUEUE).build();}@Bean("deadBind")public Binding deadBind(@Qualifier("deadExchange") Exchange ackExchange,@Qualifier("deadQueue") Queue queue){return BindingBuilder.bind(queue).to(ackExchange).with("dead").noargs();}

然后生产者代码没什么变化

 @RequestMapping("ttl")public String TTLPro(){String s1="ttl test";Message message=new Message(s1.getBytes(StandardCharsets.UTF_8));
//        message.getMessageProperties().setExpiration("10000");RabbitTemplate.convertAndSend(Constants.TTL_EXCHANGE,"ttl",message);return "发送成功";}

只不过消费者订阅的是死信队列

@RabbitListener(queues = Constants.DEAD_QUEUE)public void ListenerQueue2(Message message,Channel channel) throws IOException {long Tag=message.getMessageProperties().getDeliveryTag();try {System.out.println("接收到消息: "+ new String(message.getBody())+" TagID: "+Tag);int num=3/0;     //模拟失败channel.basicAck(Tag,false);System.out.println("处理完成");}catch (Exception e){channel.basicReject(Tag,false);}}

这样过了5s后我们就可以从死信队列中获取到延迟消息了

那我们再来通过设置消息的ttl来看一下

首先我们要把队列的ttl给取消掉,记得要删队列

 @Bean("ttlExchange")public Exchange ttlExchange(){return ExchangeBuilder.directExchange(Constants.TTL_EXCHANGE).durable(true).build();}@Bean("ttlQueue")public Queue ttlQueue(){return QueueBuilder.durable(Constants.TTL_QUEUE).deadLetterExchange(Constants.DEAD_EXCHANGE).deadLetterRoutingKey("dead").build();}@Bean("ttlBind")public Binding ttlBind(@Qualifier("ttlExchange") Exchange ackExchange,@Qualifier("ttlQueue") Queue queue){return BindingBuilder.bind(queue).to(ackExchange).with("ttl").noargs();}@Bean("deadExchange")public Exchange deadExchange(){return ExchangeBuilder.directExchange(Constants.DEAD_EXCHANGE).durable(true).build();}@Bean("deadQueue")public Queue deadQueue(){return QueueBuilder.durable(Constants.DEAD_QUEUE).build();}@Bean("deadBind")public Binding deadBind(@Qualifier("deadExchange") Exchange ackExchange,@Qualifier("deadQueue") Queue queue){return BindingBuilder.bind(queue).to(ackExchange).with("dead").noargs();}

  然后我们发送一个ttl时间为10s的,再发送一个5s的,我们知道这样两条数据是会发生错误的,因为我们设置消息过期时间,我们RabbitMQ(性能问题)并不会遍历整个消息队列看看谁过没过期,如果过期的消息不在队头,那么只有当使用的时候,才会真正的进行一些过期处理,比如传给死信交换机 

@RequestMapping("ttl")public String TTLPro(){String s1="ttl test";Message message=new Message(s1.getBytes(StandardCharsets.UTF_8));message.getMessageProperties().setExpiration("10000");RabbitTemplate.convertAndSend(Constants.TTL_EXCHANGE,"ttl",message);message.getMessageProperties().setExpiration("5000");RabbitTemplate.convertAndSend(Constants.TTL_EXCHANGE,"ttl",message);return "发送成功";}

如果正常,会在5s后接收到第一个消息,在10s后接收到第二个消息,但是此时我们会同一时间(10s)接收到两条消息

  那这个问题在上一篇ttl的时候就说过了,这里依然是个问题,虽然设置队列的ttl不会有这个问题,但是设置队列ttl我们针对不同延迟时间就需要创建多个队列,这是不太合理的,所以针对这个问题,我们有一个延迟队列的插件可以使用

 3.延迟队列插件

延迟队列插件,会给我们提供一个特殊的交换机,来完成我们的延迟功能

这是我们插件的下载地址

https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases

  我们需要找到ez文件并下载,但是注意这里的版本要与你的RabbitMQ版本可以匹配,否则之后会出现问题

那插件下完后,我们要找到对应目录,下载插件

上面两个目录,我们可以任选一个下载即可,没有这个目录,我们手动创建

然后把下载的ez文件,copy到这个目录中即可,然后我们可以使用命令 rabbitmq-plugins list 来查看插件列表,看看我们有没有成功放进去,但是注意,即使我们成功放进去并成功显示了,也可能会出错,这就可能是你们下载的RabbitMQ版本与整个延迟插件的版本不匹配,重新下载其他版本即可

然后我们启动插件rabbitmq-plugins enable rabbitmq_delayed_message_exchange

之后重启服务service rabbitmq-server restart

在没有发生错误的情况下,我们就发现我们会多了一个默认的交换机

此时我们代码中就不需要声明普通交换机了而是直接使用默认交换机即可

我们生产者代码是需要改一下的,我们需要调用一个方法来设置延迟时间

@RequestMapping("/delay2")
public String delay2() {//发送带ttl的消息 rabbitTemplate.convertAndSend(Constant.DELAYED_EXCHANGE_NAME, "delayed", 
"delayed test 20s..."+new Date(), messagePostProcessor -> {messagePostProcessor.getMessageProperties().setDelayLong(20000L); return messagePostProcessor;});rabbitTemplate.convertAndSend(Constant.DELAYED_EXCHANGE_NAME, "delayed", 
"delayed test 10s..."+new Date(), messagePostProcessor -> {messagePostProcessor.getMessageProperties().setDelayLong(10000L); //设置延迟时间 return messagePostProcessor;});return "发送成功!";
}

此时我们就可以在10s正确接收一个消息,在20s正确接收另一个消息 

  注意我们使用TTL+死信时消息传递给交换机后映射之后一直在正常队列中的,等待TTL时间到了把消息给死信交换机再映射到死信队列再拿到消息,我们使用插件的时候,消息是在RabbitMQ给我们提供的那个特殊的交换机中的,等待时间到了,再映射给队列,然后从队列中拿消息

4.常见面试题

介绍下延迟队列

我们可以这样回答:

 延迟队列是一个特殊的队列,消息发送后,消费者并不会立刻拿到,而是等待一定延迟时间后才发送给消费者进行消费

 并且延迟队列的应用场景很多,比如订单支付,智能家电,以及定时邮箱

 但是延迟队列在RabbitMQ中并没有直接给我们提供,我们可以通过TTL+死信的方式或者使用延迟插件的方式来实现延迟功能

 两者的区别:

1.通过TTL+死信

 优点:比较灵活,不需要我们额外引入插件

 缺点:我们设置消息TTL的时候可能会出现顺序的问题,而且我们需要多创建死信队列和死信交换机,完成一些绑定,增加了系统的复杂性

2.基于插件实现的延迟队列

 优点:通过插件能够简化延迟消息的实现,并且避免了时序问题

 缺点:需要依赖插件,不同版本RabbitMQ需要不同版本插件,有运维工作

http://www.15wanjia.com/news/17680.html

相关文章:

  • 安徽省公共资源交易中心网站引流推广
  • 电影采集网站怎么做seo百度收录查询工具
  • 足球哪个网站做的比较好千锋教育官网
  • 广告公司起什么名字好优化师和运营区别
  • 网站建设土豆视频教程怎样建立个人网站
  • 武汉网站设计与制作百度推广一个点击多少钱
  • 云阳网站建设今天特大新闻最新消息
  • dw网页代码模板广州百度提升优化
  • 中国室内设计联盟登录aso具体优化
  • 更改网站建设报价5118关键词挖掘工具
  • 沈阳之道网站建设电商营销策略
  • 网站建设pdf网页设计作品集
  • 哪个网站专做滨水景观近期新闻大事
  • 模板网站怎么做才美观友情链接交换的作用在于
  • 装修设计比较好的网站seo研究中心
  • ie6 网站模板成都移动seo
  • web前端开发工程师发展前景seo外贸网站制作
  • 陆川建设局网站销售培训课程一般有哪些
  • 网站建设工资多少钱网络销售好做吗
  • 免费个人网站域名注册北京百度seo服务
  • 网站开发行业发展前景优化关键词哪家好
  • 表格如何给网站做链接最近新闻摘抄50字
  • 今日新闻最新头条10条国家大事seo兼职接单平台
  • javaweb网站开发的步骤如何软件网站优化公司
  • 前端开发课程郴州seo外包
  • 装饰公司名称大全简单大气百度seo优化教程
  • 昵图网站党风廉政建设软件开发公司联系方式
  • 去年做啥网站致富交换友情链接的渠道
  • 手机网站视频无法播放是怎么回事百度推广公司电话
  • 北京医疗网站建设公司排名佛山网页搜索排名提升