DirectExchange 我们可以看到上图,当消息被提供者发送到RabbitMQ后,会根据配置队列的交换以及绑定实例进行转发消息,上图只会将消息转发路由键为KEY的队列消费者对应的实现方法逻辑中,从而完成消息的消费过程...Ubuntu 安装 在Ubuntu操作系统中,我们可以直接使用APT仓库进行安装,我使用的系统版本是16.04,系统版本并不影响安装。...接口是用来回调消息发送成功后的方法,当一个消息被成功写入到RabbitMQ服务端时,就会自动的回调RabbitTemplate.ConfirmCallback接口内的confirm方法完成通知,QueueMessageService...,如果你得项目中使用多个队列,建议每一个业务逻辑创建一个配置类,分开维护,这样不容易出错。...@RabbitHandler RabbitMQ消息处理方法,该方法的参数要与rabbitmq-provider发送消息时的类型保持一致,否则无法自动调用消费方法,也就无法完成消息的消费。
二、消息持久化 RabbitMQ是支持消息持久化的,消息持久化需要设置:Exchange为持久化和Queue持久化,这样当消息发送到RabbitMQ服务器时,消息就会持久化。...怎么证明是已经持久化了呢,实际上可以找到对应的文件: ? 找到对应磁盘中的目录: ? 消息持久化可以防止消息在RabbitMQ Server中不会因为宕机重启而丢失。...当消息投递到Exchange后,会回调confirm()方法进行通知生产者 # publisher-returns:设置为true时。...当消息匹配到Queue并且失败时,会通过回调returnedMessage()方法返回消息 # spring.rabbitmq.template.mandatory: 设置为true时。...如果消费者一直没有断开连接,那Unacked的消息就会越来越多,占用内存就越来越大,最后就会出现异常。 这个问题,我没法用我的电脑演示,我的电脑太卡了。
二、为什么使用消息队列 主要有三个作用: 解耦。如图所示。假设有系统B、C、D都需要系统A的数据,于是系统A调用三个方法发送数据到B、C、D。这时,系统D不需要了,那就需要在系统A把相关的代码删掉。...只需要创建一个类,@RabbitListener注解写上监听队列的名称,如图所示: ? 这里有个小坑,一开始RabbitMQ服务器里还没有创建队列: ? 这时如果启动消费者,会报错: ?...最好的方法是生产者和消费者都尝试创建队列,怎么写呢,有很多方式,我这里用一个相对简单一点的: 生产者的配置类加点东西: //实现BeanPostProcessor类,使用Bean的生命周期函数 @Component...使用POSTMAN进行发送消息,测试: ? 然后可以看到控制台,两个队列同时都收到了相同的消息,形成了发布订阅的效果: ?...跟上面示意图一样~证明没有问题,一切尽在掌握之中。使用POSTMAN发送,测试全匹配的队列A: ? ? 再测试部分匹配的队列B: ? ? 总结 这篇文章就先写到这里了。
目录基本介绍使用场景springboot代码演示 演示架构工程概述RabbitConfig配置类:创建队列及交换机并进行绑定MessageService业务类:发送消息及接收消息主启动类RabbitMq01Application...可以使用Topic交换机解决这个问题 使用场景适用场景:当消费端出现比较挑剔的消费者时,这时候就需要用到direct类型了,路由模式需要使用此交换机。...// 消息属性 byte[] body // 消息内容 @RabbitListener 使用 @RabbitListener 注解标记方法,当监听到队列 debug 中有消息时则会进行接收并处理...该接口中,只有一个run方法,他执行的时机是:spring容器启动完成之后,就会紧接着执行这个接口实现类的run方法。...: queue.direct.b接收到消息:hello world我正在参与2023腾讯技术创作特训营第二期有奖征文,瓜分万元奖池和键盘手表
,此队列会被删除,默认为false autoDelete 是否自动删除,当队列没有消息一段时间后自动删除,默认为false arguments 参数,可以设置队列的最大消息数等 创建此队列的生产者类...为#时,它便成为了扇形交换机当router_key没有出现*和#时,它便成为了直连交换机 Headers exchange amq.match (and amq.headers in RabbitMQ)...2)消息推送,找到了交换机,但找不到队列 交换机,队列可以声明,但不用绑定。...这样就算找到了交换机,也找不到队 可以看到,confirm和returnedMessage的方法都进行了调用 3)消息推送,交换机和队列都没有找到 和第一种情况一致,交换机都找不到了,还会去找队列吗?...4)消息推送成功 仅推送了confirm方法 小结: confirm方法,消息是否到达交换机,无论成功还是失败都会调用 returnedMessage方法,仅当没有找到队列时,才会调用 在上面的示例中
:实现ApplicationRunner接口----基本介绍Fanout Exchange交换机:当一个Msg发送到扇形交换机X上时,则扇形交换机X会将消息分别发送给所有绑定到X上的消息队列。...扇形交换机将消息路由给绑定到自身的所有消息队列,也就是说路由键在扇形交换机里没有作用,故消息队列绑定扇形交换机时,路由键可为空。扇形交换机将消息路由给绑定到他身上的所有队列,给不理会绑定的路由键。...某个扇形交换机上,当有消息发送到该扇形交换机上时,交换机会将消息的拷贝分别发送给这所有与之绑定的队列中。...// 消息属性 byte[] body // 消息内容 @RabbitListener 使用 @RabbitListener 注解标记方法,当监听到队列 debug 中有消息时则会进行接收并处理...该接口中,只有一个run方法,他执行的时机是:spring容器启动完成之后,就会紧接着执行这个接口实现类的run方法。
这两种方式都不是很优雅,使用消息总线,可以很方便解决这个问题, A 调用 B 服务后,只需要监听 B 处理完成的消息,当 B 处理完成后,会发送一条消息给 MQ,MQ 会将此 消息转发给 A 服务。...TCP三次握手过程 第一次握手:主机A通过向主机B 发送一个含有同步序列号的标志位的数据段给主机B,向主机B 请求建立连接,通过这个数据段, 主机A告诉主机B 两件事:我想要和你通信;你可以用哪个序列号作为起始数据段来回应我...比如确认号为X,则表示前X-1个数据段都收到了,只有当ACK=1时,确认号才有效,当ACK=0时,确认号无效,这时会要求重传数据,保证数据的完整性。 ...测试zs.fanout(广播) 同上面测试一样,发送一条消息给 ls 但是查看消息队列时会发现,zs.fanout下的所有消息队列都接收到了 但是,在查看ls所收到的消息时,始终都是之前那一条: 由于消息获取来之后并没有给消息队列进行应答...应用场景:为了保证订单业务的消息数据不丢失,需要使用到 RabbitMQ 的死信队列机制,当消息消费发生异常时,将消息投入死信队列中.还有比如说: 用户在商城下单成功并点击去支付后在指定时间未支付时自动失效
于是,我开始思考,如何才能进行RabbitMQ的消息可靠投递呢?特别是在这样比较极端的情况,RabbitMQ集群不可用的时候,无法投递的消息该如何处理呢?...在发送消息的方法上加上 @Transactional 注解,这样在该方法中发生异常时,消息将不会发送。...当 msg 的值为 exception 时, 在调用rabbitTemplate.convertAndSend 方法之后,程序抛出了异常,消息并没有发送出去,而是被当前事务回滚了。...类,然后实现其confirm 方法,即可用其接收服务器回调。...以下是我盗来的图,原谅我偷懒不想画了[手动狗头]: ? 另外,还需要注意的是,如果将消息发布到不存在的交换机上,那么发布用的信道将会被RabbitMQ关闭。
本文口味:爆炒鱿鱼 预计阅读:15分钟 一、说明 RabbitMQ是流行的开源消息队列系统,使用erlang语言开发,由于其社区活跃度高,维护更新较快,性能稳定,深得很多企业的欢心(当然,也包括我现在所在公司...为了保证订单业务的消息数据不丢失,需要使用到RabbitMQ的死信队列机制,当消息消费发生异常时,将消息投入死信队列中。...最终,在官网文档中找到了我想要的答案,通过官网文档的学习,才发现对于死信队列存在一些误解,导致配置死信队列之路困难重重。...“死信”是RabbitMQ中的一种消息机制,当你在消费消息时,如果队列里的消息出现以下情况: 消息被否定确认,使用 channel.basicNack 或 channel.basicReject ,并且此时...死信交换机将消息投入相应的死信队列 死信队列的消费者消费死信消息 死信消息是RabbitMQ为我们做的一层保证,其实我们也可以不使用死信队列,而是在消息消费异常时,将消息主动投递到另一个交换机中,当你明白了这些之后
可以手动创建虚拟host,创建用户,分配权限,创建交换机,创建队列等等,还有查看队列消息,消费效率,推送效率等等。 以上这些管理界面的操作在这篇暂时不做扩展描述,我想着重介绍后面实例里会使用到的。...此参考优先级高于durable // autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。...因为我们目前还没弄消费者 rabbitmq-consumer,消息没有被消费的,我们去rabbitMq管理页面看看,是否推送成功: ?...可以看到只要发送到 fanoutExchange 这个扇型交换机的消息, 三个队列都绑定这个交换机,所以三个消息接收类都监听到了这条消息。...到了这里其实三个常用的交换机的使用我们已经完毕了,那么接下来我们继续讲讲消息的回调,其实就是消息确认(生产者推送消息成功,消费者接收消息成功)。
RabbitMQ的重回队列解决了RabbitMQ由于异常情况导致消息收不到的原因,但是一般在企业不怎么实用重回队列,更多使用的是死信队列的机制,这样来保障消费端能够接收到具体的消息,其实本质上都是为了消息消费者这层的可靠性的保障机制...一、什么是死信队列 死信队列全名称是Dead Letter Exchange,所以私信队列简称是DLX,当生产者发送一个消息后,消费端未接收到,那么这个消息就会到死信队列中来保障消息的消费。...在RabbitMQ的消息消费的处理机制中,当队列中存在死信时,RabbitMQ就会自动的切换到重新发布的Exchange中,从而到新的队列机制来保障消费者这边消费数据。...是没有任何的问题的,只不过在消息发送的过程中,可能由于A的消息队列达到最大,或者是TTL过期,以及消费端被拒绝接收消息,那么在这种情况下,就会把消费端需要接收的消息切换到B中,那么这个B就是死信队列,当然这中间死信队列的...e){ e.printStackTrace(); } } } 在使用死信队列的机制中,我们一定得申明死信队列的机制,也就是代码: arguments.put
批量确认:批量其实是一个节约资源的操作,但是在RabbitMq中我们使用批量操作会造成消息重复消费,原因是批量操作是使客户端程序定期或者消息达到一定量,来调用方法等待Broker返回,这样其实是一个提高效率的做法...} ReturnCallback 通过实现 ReturnCallback 接口,启动消息失败返回,此接口是在交换器路由不到队列时触发回调,该方法可以不使用,因为交换器和队列是在代码里绑定的,如果消息成功投递到...到此,我们完成了生产者的异步确认,我们可以在回调函数中对当前失败的消息进行补偿,这样保证了我们没有发送成功的数据也被观察到了,比如某某条数据需要发送到消费者消费,但是没有发送成功,这就需要你在此做一些其他操作喽..." + message.getMessageProperties().getConsumerQueue() + ",接收到了回调方法"); } catch (Exception e) {...投递的这条消息的唯一标识 ID,是一个单调递增的正整数,delivery tag 的范围仅限于 Channel multiple:为了减少网络流量,手动确认可以被批处理,当该参数为 true 时,则可以一次性确认
可以手动创建虚拟host,创建用户,分配权限,创建交换机,创建队列等等,还有查看队列消息,消费效率,推送效率等等。 以上这些管理界面的操作在这篇暂时不做扩展描述,我想着重介绍后面实例里会使用到的。...此参考优先级高于durable // autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。...这个扇型交换机的消息, 三个队列都绑定这个交换机,所以三个消息接收类都监听到了这条消息。...到了这里其实三个常用的交换机的使用我们已经完毕了,那么接下来我们继续讲讲消息的回调,其实就是消息确认(生产者推送消息成功,消费者接收消息成功)。...②消息推送到server,找到交换机了,但是没找到队列 这种情况就是需要新增一个交换机,但是不给这个交换机绑定队列,我来简单地在DirectRabitConfig里面新增一个直连交换机,名叫‘lonelyDirectExchange
* 比如根据发送消息时指定的routingKey找不到队列时会触发 * 使用该功能需要开启确认,spring-boot中配置如下: * spring.rabbitmq.publisher-returns...; } 三,开始测试 1,写抢单测试类 写抢单测试类,我们使用jweter压力测试工具开启1000个线程进行测试(开启多线程并发测试),所以为了区别每一个模拟的用户,使用userId累加的方式进行区分...return "发送消息成功"; } 2,配置rabbitmq监听方法 rabbitmq监听上篇文章也说过了,作用就是监听指定队列中收到来自交换机的消息,来一条收一条,收完为止!...* @RabbitListener 可以标注在类上面,需配合 @RabbitHandler 注解一起使用 * @RabbitListener 标注在类上面表示当有收到消息的时候,就交给... 使用RabbitMQ的最主要变化就是:以前抢单操作请求直接由我们抢单应用程序执行,现在请求被转移到了RabbitMQ服务器中。
上这种情况,我们都是假设A B 和 M之间不会丢失消息,如果在上面的 3 、5 步骤中发生丢失消息的情况就会出现问题,针对以上情况,有如下解决方案: 针对步骤3 当M收到一条事务型消息后便开始计时,如果到了超时时间也没收到系统...如果重试3次之后仍然投递失败,那么这条消息就需要人工干预。 准备 系统A、系统B、消息中间件使用RabbitMQ、测试工具Jmeter。...不过这个案例并不是完全按照上面说到的那样,主要区别在于: A向M发一条消息,并没有写一条消息到RabbitMQ,而仅仅是向event里面写了一条记录 为了防止A向M提交Confirm和Cancle指令时失败...然后再根据这些消息的uuid去A的相关业务表查找记录,如果找到了,就置为Confirm,没找到就置为Cancel,然后再根据这两种状态分别进行不同的操作,Cancel就将消息删除;Confirm就发送一条消息到...当B中的业务代码出现问题时,A并没有提供相应的回滚接口。
标志位设置为true时,如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,那么会调用basic.return方法将消息返回给生产者(Basic.Return + Content-Header...+ Content-Body);当mandatory设置为false时,出现上述情形broker会直接将消息扔掉。...默认是false】【当immediate标志位设置为true时,如果exchange在将消息路由到queue(s)时发现对于的queue上么有消费者,那么这条消息不会放入队列中。...当与消息routeKey关联的所有queue(一个或者多个)都没有消费者时,该消息会通过basic.return方法返还给生产者。...假设有两个消费者,一个定义当前参数未设置为 A,一个设置 2 为 B,当生产者发送 100 条消息给消费者时,B 轮询接收到了 2 条消息后将停止消息接收,直到轮询时 B 可再次接收消息时再次接收】【是否将当前设置应用于整个
这两种方式都不是很优雅, 使用消息总线,可以很方便解决这个问题,A 调用 B 服务后,只需要监听 B 处理完成的消息,当 B 处理完成后,会发送一条消息给 MQ, MQ 会将此 消息转发给 A 服务。...当多个不同的用户使用同一个 RabbitMQ server 提供的服务时,可以划分出多个 vhost,每个用户在自己的 vhost 创建 exchange/ queue 等 Connection: publisher...confirm 模式最大的好处在于他是异步的,一旦发布一条消息,生产者应用程序就可以在等信道返回确认的同时继续发送下一条消息,当消息最终得到了确认之后,生产者应用便可以通过回调方法来处理确认消息,如果RabbitMQ...4.2 开始发布确认的方法 发布确认默认是没有开启的,如果要开启需要调用方法 confirmSelect,每当你要想使用发布确认,都需要在 channel 上调用该方法 Channel channel...这两种方式都不是很优雅, 使用消息总线,可以很方便解决这个问题,A 调用 B 服务后,只需要监听 B 处理完成的消息,当 B 处理完成后,会发送一条消息给 MQ, MQ 会将此 消息转发给 A 服务。
JmsTemplate:用于发送和接收消息的模板类,是Spring提供的,只需向Spring容器内注册这个类就可以使用JmsTemplate方便的操作Jms,JmsTemplate类是线程安全的,可以在整个应用范围使用...,但是进程启动成功,是因为b节点和c节点配置的是master和slave,现,b节点获取到了共享文件夹的主动权,c节点正在等待获得资源,并且提供服务 #此时关掉b节点 [root@localhost activemq_colony...运行条件前提:保证优惠券表中有c0000优惠券信息(且优惠券状态是null) 结果:订单虽然未创建,但是优惠券被锁了(被使用了) 分析原因:当接口调用失败时,订单系统事务回滚,提示用户操作失败 误区:接口出错的情况下...(MQConsumer.class); //此注解用于当创建此类对象时初始化此方法 Connection connect=null; Channel channel=null;...十一、消息队列有什么缺点 分析:一个使用了MQ的项目,如果连这个问题都没有考虑过,就把MQ引进去了,那就给自己的项目带来了风险。我们引入一个技术,要对这个技术的弊端有充分的认识,才能做好预防。
领取专属 10元无门槛券
手把手带您无忧上云