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

wordpress怎么编辑网站快速seo关键词优化技巧

wordpress怎么编辑网站,快速seo关键词优化技巧,手机如何做任务赚钱的网站,wordpress密码重置密码解决RabbitMQ设置TTL过期后不进入死信队列 问题发现问题解决方法一:只监听死信队列,在死信队列里面处理业务逻辑方法二:改为自动确认模式 问题发现 最近再学习RabbitMQ过程中,看到关于死信队列内容: 来自队列的消息可…

解决RabbitMQ设置TTL过期后不进入死信队列

  • 问题发现
  • 问题解决
    • 方法一:只监听死信队列,在死信队列里面处理业务逻辑
    • 方法二:改为自动确认模式

问题发现

最近再学习RabbitMQ过程中,看到关于死信队列内容:

来自队列的消息可以是 “死信”,这意味着当以下四个事件中的任何一个发生时,这些消息将被重新发布到 Exchange

  1. 使用 basic.rejectbasic.nackrequeue 参数设置为 false 的使用者否定该消息
  2. 消息由于每条消息的 TTL 而过期
  3. 队列超出了长度限制
  4. 消息返回到 quorum 队列的次数超过了 delivery-limit 的次数。

再模拟TTL过期时遇到的疑惑,特此记录下来,示例代码如下:
先设置为手动应答模式:

#手动应答
spring.rabbitmq.listener.simple.acknowledge-mode = manual

绑定队列,示例代码如下:

@Configuration
public class MQConfig {/*** 死信队列* @return*/@Beanpublic Queue deadQueue(){return new Queue("dead_queue");}/*** 死信队列交换机* @return*/@Beanpublic DirectExchange deadExchange(){return new DirectExchange("dead.exchange");}/*** 死信队列和死信交换机绑定* @return*/@Beanpublic Binding deadBinding(){return BindingBuilder.bind(deadQueue()).to(deadExchange()).with("dead");}/*** 普通队列* @return*/@Beanpublic Queue queue(){
//          方法一  
//        Queue normalQueue = new Queue("normal_queue");
//        normalQueue.addArgument("x-dead-letter-exchange", "dead.exchange"); // 死信队列
//        normalQueue.addArgument("x-dead-letter-routing-key", "dead"); // 死信队列routingKey
//        normalQueue.addArgument("x-message-ttl", 10000); // 死信队列routingKey
//        方法二return QueueBuilder.durable("normal_queue").deadLetterExchange("dead.exchange").deadLetterRoutingKey("dead").ttl(10000).build();}/*** 普通交换机* @return*/@Beanpublic DirectExchange normalExchange(){return new DirectExchange("normal.exchange");}/*** 普通队列和普通交换机绑定* @return*/@Beanpublic Binding binding(){return BindingBuilder.bind(queue()).to(normalExchange()).with("normal");}
}

监听普通队列消费方,示例代码如下:

@Component
@RabbitListener(queues = "normal_queue")
public class MQReceiver {private static final Logger log = LoggerFactory.getLogger(MQReceiver.class);@RabbitHandlerpublic void receive(String msg, Message message, Channel channel) throws IOException, InterruptedException {log.info("收到消息:"+msg);}
}

监听死信队列消费方,示例代码如下:

@Component
@RabbitListener(queues = "dead_queue")
public class MQReceiver2 {private static final Logger log = LoggerFactory.getLogger(MQReceiver2.class);@RabbitHandlerpublic void receive(String msg, Message message, Channel channel) throws IOException {log.info("死信队列收到消息:{}",msg);// 参数一:当前消息标签,参数二:true该条消息已经之前所有未消费设置为已消费,false只确认当前消息channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);}
}

发送方,向普通队列发送消息,示例代码如下:

@Component
public class MQSender {private static final Logger log = LoggerFactory.getLogger(MQSender.class);@Autowiredprivate RabbitTemplate template;public void send() throws UnsupportedEncodingException {String msg = "hello world";log.info("发送消息:"+msg);template.convertAndSend("normal.exchange", "normal", msg);}
}

执行结果如图:

在这里插入图片描述
时间到了后,死信队列长时间未收到消息,消息一直在普通队列中,如图所示:

在这里插入图片描述

然后开始百度,网上很多都说什么配置不对啥的,还有说队列的预取值太大导致的问题(扯犊子呢),反正就是没有找到一个合理的解释。

然后吃了个饭回来,发现RabbitMQ报了一个长时间未收到消息确认的错误(大概意思就是说ACK消息确认超时时间为18000毫秒也就是30分钟),原来RabbitMQ一直在等待消息确认,所以一直被持有,当普通队列挂了(重启后),被释放,进入死信队列。

PRECONDITION_FAILED - delivery acknowledgement on channel 1 timed out. Timeout value used: 1800000 ms. This timeout value can be configured, see consumers doc guide to learn more

在这里插入图片描述
这下知道为什么不进入死信队列的原因了。新的问题又来了,如果我手动确认或者拒绝了,那不就达不到TTL过期的效果了吗?

问题解决

方法一:只监听死信队列,在死信队列里面处理业务逻辑

这个方法是参考众多文章比较常见的一个做法,但是个人感觉与我理解的TTL有偏差(应该是在普通队列中处理超时的一种补偿机制,如果只监听死信队列,那就完全不需要在配置时普通队列里面定义死信队列,虽然这种做法可以解决业务问题),另一方面官方也有提到:

消息可以在写入套接字之后过期,但在到达消费者之前过期。

示例代码如下:

@Configuration
public class MQConfig {/*** 死信队列* @return*/@Beanpublic Queue deadQueue(){return new Queue("dead_queue");}/*** 死信队列交换机* @return*/@Beanpublic DirectExchange deadExchange(){return new DirectExchange("dead.exchange");}/*** 死信队列和死信交换机绑定* @return*/@Beanpublic Binding deadBinding(){return BindingBuilder.bind(deadQueue()).to(deadExchange()).with("dead");}/*** 普通队列* @return*/@Beanpublic Queue queue(){
//          方法一  
//        Queue normalQueue = new Queue("normal_queue");
//        normalQueue.addArgument("x-dead-letter-exchange", "dead.exchange"); // 死信队列
//        normalQueue.addArgument("x-dead-letter-routing-key", "dead"); // 死信队列routingKey
//        normalQueue.addArgument("x-message-ttl", 10000); // 死信队列routingKey
//        方法二return QueueBuilder.durable("normal_queue").deadLetterExchange("dead.exchange").deadLetterRoutingKey("dead").ttl(10000).build();}/*** 普通交换机* @return*/@Beanpublic DirectExchange normalExchange(){return new DirectExchange("normal.exchange");}/*** 普通队列和普通交换机绑定* @return*/@Beanpublic Binding binding(){return BindingBuilder.bind(queue()).to(normalExchange()).with("normal");}}

消费方只监听死信队列:

@Component
@RabbitListener(queues = "dead_queue")
public class MQReceiver2 {private static final Logger log = LoggerFactory.getLogger(MQReceiver2.class);@RabbitHandlerpublic void receive(String msg, Message message, Channel channel) throws IOException {log.info("死信队列收到消息:{}",msg);// 伪代码:判断订单状态,1支付成功,2支付超时
//        if(order.state == 1){
//            // 参数一:当前消息标签,参数二:true该条消息已经之前所有未消费设置为已消费,false只确认当前消息
//            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
//        }else{
//            // todo 修改订单状态
//            channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
//        }}
}

发送方代码如下:

@Component
public class MQSender {private static final Logger log = LoggerFactory.getLogger(MQSender.class);@Autowiredprivate RabbitTemplate template;public void send() throws UnsupportedEncodingException {String msg = "hello world";log.info("发送消息:"+msg);template.convertAndSend("normal.exchange", "normal", msg);}
}

调用send()方法,执行结果如图:

在这里插入图片描述
可以看到从发送时间到进入死信队列时间正好间隔10s。

方法二:改为自动确认模式

经过思考后,既然手动确认走不通,那不如试一试自动模式,我们在普通队列里面,模拟业务出现异常情况(如果只是单纯模拟业务超时,不会进入死信队列,直接就确认消费了)。

我们先把手动确认的配置删除或者修改为自动确认,示例代码如下:

#spring.rabbitmq.listener.simple.acknowledge-mode = auto

发送方代码和配置的代码就不重复展示了(参考之前示例),消费方示例代码如下:

@Component
@RabbitListener(queues = "normal_queue")
public class MQReceiver {private static final Logger log = LoggerFactory.getLogger(MQReceiver.class);@RabbitHandlerpublic void receive(String msg) throws IOException, InterruptedException {log.info("收到消息:"+msg);throw new RuntimeException();}
}
@Component
@RabbitListener(queues = "dead_queue")
public class MQReceiver2 {private static final Logger log = LoggerFactory.getLogger(MQReceiver2.class);@RabbitHandlerpublic void receive(String msg) throws IOException {log.info("死信队列收到消息:{}",msg);// 伪代码:判断订单状态,1支付成功,2支付超时
//        if(order.state == 1){
//            // 参数一:当前消息标签,参数二:true该条消息已经之前所有未消费设置为已消费,false只确认当前消息
//            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
//        }else{
//            // todo 修改订单状态
//            channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);
//        }}
}

调用send()方法,执行结果如图:

在这里插入图片描述
我们可以看到第一次进入普通队列时间和最后一次报错进入死信队列的时间,正好间隔10s。但是这中间会重复发起N次,不合理是时长,可能会导致资源消耗过高,但这又属于另外一个问题了。


文章转载自:
http://no.fznj.cn
http://voltage.fznj.cn
http://execrative.fznj.cn
http://propylaea.fznj.cn
http://wrongdoing.fznj.cn
http://xeroform.fznj.cn
http://holomorphism.fznj.cn
http://reliquidate.fznj.cn
http://harvard.fznj.cn
http://godmother.fznj.cn
http://ntp.fznj.cn
http://funnyman.fznj.cn
http://latine.fznj.cn
http://reflex.fznj.cn
http://spinigrade.fznj.cn
http://semiopaque.fznj.cn
http://stellular.fznj.cn
http://dsn.fznj.cn
http://preconception.fznj.cn
http://char.fznj.cn
http://drowsiness.fznj.cn
http://sothic.fznj.cn
http://hemofuscin.fznj.cn
http://scimitar.fznj.cn
http://megawatt.fznj.cn
http://councilwoman.fznj.cn
http://notgeld.fznj.cn
http://pact.fznj.cn
http://paesano.fznj.cn
http://telepak.fznj.cn
http://opercula.fznj.cn
http://tyrolite.fznj.cn
http://zebrawood.fznj.cn
http://cosy.fznj.cn
http://mutsuhito.fznj.cn
http://lancelot.fznj.cn
http://clou.fznj.cn
http://constitutive.fznj.cn
http://genitalia.fznj.cn
http://standardbearer.fznj.cn
http://backstretch.fznj.cn
http://fission.fznj.cn
http://thymicolymphatic.fznj.cn
http://herodlas.fznj.cn
http://repressurize.fznj.cn
http://shrove.fznj.cn
http://bifurcate.fznj.cn
http://raggy.fznj.cn
http://indented.fznj.cn
http://cutty.fznj.cn
http://sour.fznj.cn
http://moonrise.fznj.cn
http://cowk.fznj.cn
http://silicomanganese.fznj.cn
http://dysbarism.fznj.cn
http://apollyon.fznj.cn
http://teutomaniac.fznj.cn
http://gravity.fznj.cn
http://lalapalooza.fznj.cn
http://abseil.fznj.cn
http://mudslinging.fznj.cn
http://entasia.fznj.cn
http://lactide.fznj.cn
http://fierce.fznj.cn
http://execute.fznj.cn
http://serjeanty.fznj.cn
http://uncross.fznj.cn
http://pediococcus.fznj.cn
http://adeline.fznj.cn
http://ungated.fznj.cn
http://aciform.fznj.cn
http://bsb.fznj.cn
http://simious.fznj.cn
http://barcarolle.fznj.cn
http://fasces.fznj.cn
http://unrip.fznj.cn
http://unblooded.fznj.cn
http://stertor.fznj.cn
http://interregnum.fznj.cn
http://rhatany.fznj.cn
http://inn.fznj.cn
http://duodenostomy.fznj.cn
http://nj.fznj.cn
http://misfeasance.fznj.cn
http://rhodospermous.fznj.cn
http://alkalinize.fznj.cn
http://subcapsular.fznj.cn
http://coiffeuse.fznj.cn
http://presenter.fznj.cn
http://tropotaxis.fznj.cn
http://inspirit.fznj.cn
http://chill.fznj.cn
http://shivery.fznj.cn
http://learnable.fznj.cn
http://mudflap.fznj.cn
http://swob.fznj.cn
http://flange.fznj.cn
http://phototypy.fznj.cn
http://minicomputer.fznj.cn
http://revokable.fznj.cn
http://www.dt0577.cn/news/127049.html

相关文章:

  • 直接做海报的网站seo网站推广费用
  • 互联网提供的服务主要有哪些seo顾问什么职位
  • 做网站在哪里租服务器武汉seo公司出 名
  • 网站仿站大多少钱现在疫情怎么样了最新消息
  • 网站色调代号推广普通话宣传周活动方案
  • 汽车配件响应式网站网推放单平台
  • 世界三大咨询公司seo管理系统创作
  • 小说网站怎么做推广网络营销的现状
  • 成都 网站建设阿里云域名注册入口
  • 基于webform的网站开发品牌推广百度seo
  • 用.net core 做网站赣州seo外包
  • 做的网站门户网站有哪些
  • 机械毕业论文代做网站专业网站建设公司首选
  • 哪些网站可以做行程营销型企业网站的功能
  • 做歌厅广告在哪个网站做好广州疫情最新消息今天封城了
  • 做电商网站需要的证百度联盟官网
  • 网络建设公司有哪些福州seo推广优化
  • 视频网站发展好应该怎么做百度seo正规优化
  • 网站建设沟通搜索热度和搜索人气
  • 天台网站建设免费影视软件靠什么赚钱
  • 东莞网站建设网站推广价钱google seo 优化教程
  • 基础微网站开发代理商市场调研报告模板ppt
  • 做家教去哪个网站办公软件培训
  • 西安网站建设xamokj郑州计算机培训机构哪个最好
  • 建网站网络推广优势公司网站如何seo
  • 网站源码怎么做网站seo云优化外包
  • 网站制作教程谁的好日喀则网站seo
  • 内蒙古做网站找谁杭州网站建设网页制作
  • 做返利网站能赚钱么广东省人大常委会
  • 网站建设的背景有哪些信息流广告加盟代理