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

html留言簿网站基本框架搭建wordpress和woo

html留言簿网站基本框架搭建,wordpress和woo,迪庆北京网站建设,17网站一起做网店广州沙河目录 发送方确认 添加配置 常量类 声明队列和交换机并绑定二者关系 confirm确认模式 编写生产消息代码 生产消息1 解决方法 多次生产消息2 解决方法 生产消息3 return 模式 编写生产消息代码#xff08;路由正确#xff09; 生产消息1 编写生产消息代码… 目录 发送方确认 添加配置 常量类 声明队列和交换机并绑定二者关系 confirm确认模式  编写生产消息代码 生产消息1 解决方法 多次生产消息2 解决方法 生产消息3 return 模式 编写生产消息代码路由正确 生产消息1 编写生产消息代码路由错误 生产消息2 面试题 发送方确认 在使⽤ RabbitMQ的时候, 可以通过消息持久化来解决因为服务器的异常崩溃⽽导致的消息丢失, 但是还有⼀个问题, 当消息的⽣产者将消息发送出去之后, 消息到底有没有正确地到达服务器呢? 如果在消息到达服务器之前已经丢失(⽐如RabbitMQ重启, 那么RabbitMQ重启期间⽣产者消息投递失败), 持久化操作也解决不了这个问题因为消息根本没有到达服务器何谈持久化? RabbitMQ为我们提供了两种解决⽅案 a. 通过事务机制实现 b. 通过发送⽅确认(publisher confirm) 机制实现 事务机制⽐较消耗性能, 在实际⼯作中使⽤也不多, 下面主要介绍confirm机制来实现发送⽅的确认. RabbitMQ为我们提供了两个⽅式来控制消息的可靠性投递 1. confirm确认模式 2. return退回模式 添加配置 spring:application:name: rabbit-extensions-demorabbitmq:addresses: amqp://study:study47.98.109.138:5672/extensionpublisher-confirm-type: correlated #消息发送确认 常量类 public class Constants {//发送方确认public static final String CONFIRM_QUEUE confirm.queue;public static final String CONFIRM_EXCHANGE confirm.exchange; } 声明队列和交换机并绑定二者关系 import org.springframework.amqp.core.*; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import rabbitextensionsdemo.constant.Constants;Configuration public class RabbitMQConfig {//发送方确认Bean(confirmQueue)public Queue confirmQueue(){return QueueBuilder.durable(Constants.CONFIRM_QUEUE).build();}Bean(confirmExchange)public DirectExchange confirmExchange(){return ExchangeBuilder.directExchange(Constants.CONFIRM_EXCHANGE).build();}Bean(confirmBinding)public Binding confirmBinding(Qualifier(confirmQueue) Queue queue, Qualifier(confirmExchange) Exchange exchange){return BindingBuilder.bind(queue).to(exchange).with(confirm).noargs();} } confirm确认模式  Producer 在发送消息的时候, 对发送端设置⼀个ConfirmCallback的监听, ⽆论消息是否到达 Exchange, 这个监听都会被执⾏, 如果Exchange成功收到, ACK( Acknowledge character , 确认字符)为true, 如果没收到消息, ACK就为false。 RabbitTemplate.ConfirmCallback 和 ConfirmListener 区别 在RabbitMQ中, ConfirmListener和ConfirmCallback都是⽤来处理消息确认的机制, 但它们属于不同的客⼾端库, 并且使⽤的场景和⽅式有所不同. 1. ConfirmListener 是 RabbitMQ Java Client 库中的接⼝. 这个库是 RabbitMQ 官⽅提供的⼀个直接与RabbitMQ服务器交互的客⼾端库. ConfirmListener 接⼝提供了两个⽅法: handleAck 和handleNack, ⽤于处理消息确认和否定确认的事件. 2. ConfirmCallback 是 Spring AMQP 框架中的⼀个接⼝. 专⻔为Spring环境设计. ⽤于简化与 RabbitMQ交互的过程. 它只包含⼀个 confirm ⽅法⽤于处理消息确认的回调. 在 Spring Boot 应⽤中, 通常会使⽤ ConfirmCallback, 因为它与 Spring 框架的其他部分更加整合, 可以利⽤ Spring 的配置和依赖注⼊功能. ⽽在使⽤ RabbitMQ Java Client 库时, 则可能会直接实现ConfirmListener 接⼝, 更直接的与RabbitMQ的Channel交互 编写生产消息代码 import org.springframework.amqp.rabbit.connection.CorrelationData; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import rabbitextensionsdemo.constant.Constants;import java.util.Date;RequestMapping(/producer) RestController public class ProducerController {Autowiredprivate RabbitTemplate confirmRabbitTemplate;RequestMapping(/confirm)public String confirm() {confirmRabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {Overridepublic void confirm(CorrelationData correlationData, boolean ack, String cause) {System.out.println(执行了confirm方法);if (ack){System.out.printf(接收到消息, 消息ID: %s \n, correlationDatanull? null: correlationData.getId());}else {System.out.printf(未接收到消息, 消息ID: %s, cause: %s \n, correlationDatanull? null: correlationData.getId(), cause);//相应的业务处理}}});CorrelationData correlationData new CorrelationData(1);confirmRabbitTemplate.convertAndSend(Constants.CONFIRM_EXCHANGE, confirm, confirm test..., correlationData);return 消息发送成功;} } public interface ConfirmCallback {         /**         * 确认回调         * param correlationData: 发送消息时的附加信息 , 通常⽤于在确认回调中识别特定的消 息         * param ack: 交换机是否收到消息 , 收到为 true, 未收到为 false         * param cause: 当消息确认失败时 , 这个字符串参数将提供失败的原因 . 这个原因可以⽤于调 试和错误处理 .         * 成功时 , cause 为 null         */         void confirm ( Nullable CorrelationData correlationData, boolean ack,         Nullable String cause); } 生产消息1 第一次生产消息 第二次生产消息 此时我们看到第一次生产消息时能够正常生产消息但是当我们第二次生产消息时却抛异常了异常信息为java.lang.IllegalStateException: Only one ConfirmCallback is supported by each RabbitTemplate 解决方法 是为什么呢从异常信息中我们可以看到ConfirmCallback只能被设置一次但是从我们的代码中可以看到我们每次生产消息时都会设置一次ConfirmCallback显然这就是问题所在。 下面我们把刚刚的ConfirmCallback提取出来重新设置RabbitTemplate。 RabbitTemplateConfig import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.connection.CorrelationData; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Configuration public class RabbitTemplateConfig {Beanpublic RabbitTemplate confirmRabbitTemplate(ConnectionFactory connectionFactory){RabbitTemplate rabbitTemplate new RabbitTemplate(connectionFactory);//设置回调方法rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {Overridepublic void confirm(CorrelationData correlationData, boolean ack, String cause) {System.out.println(执行了confirm方法);if (ack){System.out.printf(接收到消息, 消息ID: %s \n, correlationDatanull? null: correlationData.getId());}else {System.out.printf(未接收到消息, 消息ID: %s, cause: %s \n, correlationDatanull? null: correlationData.getId(), cause);//相应的业务处理}}});return rabbitTemplate;} } ProducerController import org.springframework.amqp.core.Message; import org.springframework.amqp.core.MessageDeliveryMode; import org.springframework.amqp.core.MessageProperties; import org.springframework.amqp.rabbit.connection.CorrelationData; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import rabbitextensionsdemo.constant.Constants;RequestMapping(/producer) RestController public class ProducerController {Autowiredprivate RabbitTemplate rabbitTemplate;Autowiredprivate RabbitTemplate confirmRabbitTemplate;RequestMapping(/pres)public String pres() {Message message new Message(Presistent test....getBytes(), new MessageProperties());//消息持久化message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);System.out.println(message);rabbitTemplate.convertAndSend(Constants.PRES_EXCHANGE, pres, message);return 消息发送成功;}RequestMapping(/confirm)public String confirm() {CorrelationData correlationData new CorrelationData(1);confirmRabbitTemplate.convertAndSend(Constants.CONFIRM_EXCHANGE, confirm, confirm test..., correlationData);return 消息发送成功;} } 生产消息 多次生产消息2 此时我们可以看到我们解决了前面多次生产消息导致的ConfirmCallback被设置多次的问题但是我们此时的代码就真的没有问题了吗 当我们生产其它消息时发现我们并没有给这个生产消息的方法设置ConfirmCallback啊但是为什么在控制台上看到执行了我们设置的ConfrimCallback这是为什么呢 是因为我们在前面设置了RabbitTemplate而且使用了Autowired注解注入了RabbitTemplate虽然我们注入了两个一个是rabbitTemplate一个是confirmRabbitTemplate但是这两个都是同一个RabbitTemplate。 解决方法 解决办法我们在RabbitTemplateConfig中设置两个RabbitTemplate. import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.connection.CorrelationData; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Configuration public class RabbitTemplateConfig {Beanpublic RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){RabbitTemplate rabbitTemplate new RabbitTemplate(connectionFactory);return rabbitTemplate;}Beanpublic RabbitTemplate confirmRabbitTemplate(ConnectionFactory connectionFactory){RabbitTemplate rabbitTemplate new RabbitTemplate(connectionFactory);//设置回调方法rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {Overridepublic void confirm(CorrelationData correlationData, boolean ack, String cause) {System.out.println(执行了confirm方法);if (ack){System.out.printf(接收到消息, 消息ID: %s \n, correlationDatanull? null: correlationData.getId());}else {System.out.printf(未接收到消息, 消息ID: %s, cause: %s \n, correlationDatanull? null: correlationData.getId(), cause);//相应的业务处理}}});return rabbitTemplate;} } 与此同时我们修改注入方式 此时当再次使用/producer/pres来生产消息时就没问题了。 生产消息3 下面我们修改一下生产消息时给消息设置的路由规则 RequestMapping(/confirm)public String confirm() {CorrelationData correlationData new CorrelationData(1);confirmRabbitTemplate.convertAndSend(Constants.CONFIRM_EXCHANGE, confirm111, confirm test..., correlationData);return 消息发送成功;} 生产消息 我们知道上面生产消息时给消息设置的路由规则并不存在按道理说应该会打印“未收到消息”而非“收到消息”原因是因为上面的confirm确认模式是用来确定生产消息是否到达了交换机而上面的路由规则是针对消息从交换机到队列的解决上面的路由问题使用到另一种确认模式。 return 模式 消息到达Exchange之后, 会根据路由规则匹配, 把消息放⼊Queue中. Exchange到Queue的过程, 如果⼀条消息⽆法被任何队列消费(即没有队列与消息的路由键匹配或队列不存在等), 可以选择把消息退回给发送者. 消息退回给发送者时, 我们可以设置⼀个返回回调⽅法, 对消息进⾏处理。 修改RabbitTemplateConfig设置消息退回的回调方法 import org.springframework.amqp.core.ReturnedMessage; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.connection.CorrelationData; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Configuration public class RabbitTemplateConfig {Beanpublic RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){RabbitTemplate rabbitTemplate new RabbitTemplate(connectionFactory);return rabbitTemplate;}Beanpublic RabbitTemplate confirmRabbitTemplate(ConnectionFactory connectionFactory){RabbitTemplate rabbitTemplate new RabbitTemplate(connectionFactory);//设置回调方法rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {Overridepublic void confirm(CorrelationData correlationData, boolean ack, String cause) {System.out.println(执行了confirm方法);if (ack){System.out.printf(接收到消息, 消息ID: %s \n, correlationDatanull? null: correlationData.getId());}else {System.out.printf(未接收到消息, 消息ID: %s, cause: %s \n, correlationDatanull? null: correlationData.getId(), cause);//相应的业务处理}}});//消息被退回时, 回调方法rabbitTemplate.setMandatory(true);rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {Overridepublic void returnedMessage(ReturnedMessage returned) {System.out.println(消息退回:returned);}});return rabbitTemplate;} } 使⽤RabbitTemplate的setMandatory⽅法设置消息的mandatory属性为true(默认为false). 这个属性 的作⽤是告诉RabbitMQ, 如果⼀条消息⽆法被任何队列消费, RabbitMQ应该将消息返回给发送者, 此时 ReturnCallback 就会被触发。 回调函数中有⼀个参数: ReturnedMessage, 包含以下属性 public class ReturnedMessage {         //返回的消息对象包含了消息体和消息属性         private final Message message;         //由 Broker 提供的回复码 , 表⽰消息⽆法路由的原因 . 通常是⼀个数字代码每个数字代表不同 的含义 .         private final int replyCode;         //⼀个⽂本字符串 , 提供了⽆法路由消息的额外信息或错误描述 .         private final String replyText;         //消息被发送到的交换机名称         private final String exchange;         //消息的路由键即发送消息时指定的键         private final String routingKey; } 编写生产消息代码路由正确 RequestMapping(/returns)public String returns() {CorrelationData correlationData new CorrelationData(5);confirmRabbitTemplate.convertAndSend(Constants.CONFIRM_EXCHANGE, confirm, returns test..., correlationData);return 消息发送成功;} 生产消息1 编写生产消息代码路由错误 RequestMapping(/returns)public String returns() {CorrelationData correlationData new CorrelationData(5);confirmRabbitTemplate.convertAndSend(Constants.CONFIRM_EXCHANGE, confirm111, returns test..., correlationData);return 消息发送成功;} 生产消息2 此时我们可以看到队列中依旧是只有1条消息而且代码执行了消息退回而且消息退回时打印了消息信息显然我们可以看到消息的路由规则是错误的不会入队列。 面试题 如何保证RabbitMQ消息的可靠传输? 从这个图中, 可以看出, 消息可能丢失的场景以及解决⽅案 1. ⽣产者将消息发送到 RabbitMQ失败         a. 可能原因: ⽹络问题等         b. 解决办法: [发送⽅确认-confirm确认模式] 2. 消息在交换机中⽆法路由到指定队列:         a. 可能原因: 代码或者配置层⾯错误, 导致消息路由失败         b. 解决办法: [发送⽅确认-return模式] 3. 消息队列⾃⾝数据丢失         a. 可能原因: 消息到达RabbitMQ之后, RabbitMQ Server 宕机导致消息丢失.         b. 解决办法: [持久性]. 开启 RabbitMQ持久化, 就是消息写⼊之后会持久化到磁盘, 如果RabbitMQ 挂了, 恢复之后会⾃动读取之前存储的数据. (极端情况下, RabbitMQ还未持久化就挂了, 可能导致少量数据丢失, 这个概率极低, 也可以通过集群的⽅式提⾼可靠性) 4. 消费者异常, 导致消息丢失         a. 可能原因: 消息到达消费者, 还没来得及消费, 消费者宕机. 消费者逻辑有问题.         b. 解决办法: [消息确认]. RabbitMQ 提供了 消费者应答机制 来使 RabbitMQ 能够感知到消费者是否消费成功消息. 默认情况下消费者应答机制是⾃动应答的, 可以开启⼿动确认, 当消费者确认消费成功后才会删除消息, 从⽽避免消息丢失. 除此之外, 也可以配置重试机制, 当消息消费异常时, 通过消息重试确保消息的可靠性。 欢迎大家来访问我的主页----》链接
http://www.pierceye.com/news/30391/

相关文章:

  • 有哪些网站能免费建站wordpress不能登录界面
  • 公司网站建设开源平台wordpress 前台注册登录
  • 毕节市网站建设wordpress大神教程
  • 网站建设 jsp php重庆卓光科技有限公司
  • 哪个网站可以做行程表做外贸主要看什么网站
  • 网站建设进度表 免费下载wordpress 安装 重定向循环
  • 网站上的图标怎么改淘宝网站开发方式
  • 做iframe跳转怎么自适应网站泉州关键词网站排名
  • 齐齐哈尔网站设计网页设计免费模板9466
  • 可以做微信公众号封面的网站科技智库青年人才计划
  • 怎么样才能做好网站建设打不开住房和城乡建设部网站
  • word用来做网站的cc域名有哪些知名网站
  • 有没有永久免费的进销存软件seo顾问咨询
  • 音乐网站开发需求全网黄页网站
  • 免费公司主页网站wordpress列表页调用图片
  • 厦门网站建设价格xm37网站建设冫首先金手指十五
  • 网站产品怎么改顺序巧更妙改wordpress语言_wordpress英文变中文
  • 地方网站发展做一个微商城要多少钱
  • 广东省网站备案要多久网站设计模板图
  • 网站运营 解决方案凡科网站建站教程
  • 网站可以增加关键词吗电白网站开发公司
  • 做婚庆网站的想法百度竞价广告
  • 考试类网站如何做网站开发一定得用html吗
  • 电子工程设计网站中山网站建设找阿 n 2
  • 发帖子的网站wordpress 主题调试
  • 建设网站公司东莞徐州app制作
  • 江油市建设局网站襄阳建设网站
  • 做网站前端多少钱怎么做网站跳转链接
  • 网站建设推广选哪家如何制作一个单页网站
  • 服务器出租网站c2c网站 多钱