装修公司资质查询官方网站,智慧团建初始密码是什么,各类最牛网站建设,广州app开发价格表上一篇传送门#xff1a;点我
目前只学习了RabbitMQ#xff0c;后续学习了其他MQ后会继续补充。
MQ有了解过吗#xff1f;说说什么是MQ#xff1f;
MQ是Message Queue的缩写#xff0c;也就是消息队列的意思。它是一种应用程序对应用程序的通信方法#xff0c;使得应用…上一篇传送门点我
目前只学习了RabbitMQ后续学习了其他MQ后会继续补充。
MQ有了解过吗说说什么是MQ
MQ是Message Queue的缩写也就是消息队列的意思。它是一种应用程序对应用程序的通信方法使得应用程序能够通过读写出入队列的消息来进行通信而无需使用专用的连接来链接它们。消息队列中间件是分布式系统中重要的组件主要解决应用解耦异步消息流量削峰等问题实现高性能高可用可伸缩和最终一致性架构。在消息队列中有生产者和消费者两个角色。生产者负责发送数据到消息队列而消费者则从消息队列中取出数据进行处理。这种方式实现了生产者与消费者之间的解耦使得它们可以独立地运行和扩展。
消息队列的优缺点有哪些
优点 1.应用解耦消息队列允许生产者和消费者之间松耦合。生产者只需要将消息发送到队列而不需要关心消费者何时或如何处理这些消息。 2.异步处理消息队列允许异步处理消息这意味着接收者可以在自己方便的时候处理消息而不是立即响应。这可以提高系统的吞吐量和响应时间。 3.流量削峰在高并发场景下消息队列可以起到缓冲作用平滑突发流量保护后端系统免受冲击。
缺点 1.可用性降低如果消息队列服务成为单点故障整个系统可能会受到影响。因此需要实施高可用性和容错策略一般解决方法是给MQ架集群。 2.复杂性提高引入消息队列会增加系统的复杂性。因为需要配置和管理消息队列服务同时还需要处理可能的消息丢失、重复或顺序错乱等问题。 3.一致性问题在分布式系统中使用消息队列时如果消息队列发生了消息的丢失与重复则可能会遇到数据一致性的问题。
说说消息队列的应用场景
消息队列的应用场景主要分为以下三种 1.异步处理应用在实时性要求不高的一些场景例如用户注册发送验证码、下单通知发送优惠券等。这些场景下服务方只需要把协商好的消息发送到消息队列剩下的由消费者的消息服务去处理不需要等待消费者的返回结果就可以直接返回给客户端返回给业务层面 2.应用解耦可以把一些相关的但是耦合度不高的一些系统关联起来比如订单系统与优惠券积分系统有关联度但是没有那么紧密每个系统之间只需要把一些约定好的消息发送到MQ另外的系统直接去消费就可以了它可以允许各类系统间采用不同的一些框架和语言来实现从而大大增加了整个系统的灵活度 3.流量削峰应用在大流量入口的一些短时间的业务短时间内业务需求处理不完的一些服务例如双十一秒杀、演唱会抢票等。为了权衡高可用把大量的一些并行任务发送给MQ。根据MQ的存储和分发功能平稳的去处理后续的一些业务从而起到大流量缓冲的作用。
开发过程中有哪些MQ可以选择如何技术选型
目前市面上常见的消息队列中间件主要有RabbitMQ、ActiveMQ、RocketMQ、Kafka。这几种消息队列各有优缺点具体如下 由上可以看出ActiveMQ相较于其它三种消息队列可用性差并且吞吐量、消息延迟、可靠性都一般除了一些小型项目或是追求经济高效的特定需求ActiveMQ不是消息队列的第一选择所以现在ActiveMQ不是主流的消息队列了。 而由于RabbitMQ是基于Erlang语言开发的所以如果需要对现有消息队列去做进一步的开发不推荐使用RabbitMQ如果只是拿来做简单应用开发就没区别。 从吞吐量来看比较好的是RocketMQ和Kafka其中最好的是Kafka单机的并发吞吐能力能够达到百万量级所以如果要追求极致的吞吐能力去处理一些海量数据传输的大数据业务的时候Kafka会是更好的选择。 而吞吐量高也会带来一定的牺牲RocketMQ和Kafka的消息延迟毫秒级相比RabbitMQ微秒级要久很多如果要追求消息的低延迟就可以选择RabbitMQ。 从可靠性的角度来看Kafka由于追求极致的并发吞吐量所以消息可靠性一般如果要考虑消息的高可靠性可以选择RabbitMQ或RocketMQ。
说说RabbitMQ的基本架构设计
RabbitMQ的基本架构由以下几个部分组成 1.生产者Producer生产者是消息的发送方负责产生并发生消息到RabbitMQ。生产者通常将消息发生给交换机Exchange从而使其消费者没有强关联。 2.交换机Exchange交换机是消息的分发中心负责将接收到的消息路由到一个或多个消息队列。它定义了消息的传递规则可以根据规则将消息发送到一个或多个队列中。
直连交换机Direct Exchange将消息路由到与消息中的路由键Routing Key完全匹配的队列主题交换机Topic Exchange根据通配符匹配路由键Routing Key将消息路由到一个或多个队列扇出交换机Fanout Exchange将消息广播到所有与交换机绑定的队列忽略路由键头部交换机Headers Exchange根据消息头中的属性进行匹配将消息路由到与消息头匹配的队列。
3.队列Queue队列是消息的存储区用于存储生产者发送的消息。消息最终会被消费者从队列中取出并处理。每个队列都有一个名称并且可以绑定到一个或多个交换机。 4.消费者Consumer消费者是消息的接收方负责从队列中获取消息并进行处理。消费者通过订阅队列来接收消息。 5.绑定binding绑定是交换机和队列之间的关联关系。生产者将消息发送到交换机而队列通过绑定与交换机相连从而接收消息。 6.虚拟主机Virtual Host虚拟主机是RabbitMQ的基本工作单元每个虚拟主机都拥有自己独立的用户、权限、交换机、队列等资源完全隔离于其他虚拟主机。 7.连接Connection连接是指生产者、消费者与RabbitMQ之间的网络连接。每个连接都可以包含多个信道Channel每个信道是一个独立的会话通道可以进行独立的消息传递。 8.消息Message消息是生产者和消费者之间传递的数据单元。消息通常会包含消息体和可选的属性如路由键等。 说说RabbitMQ的交换机类型
1.Direct Exchange直连交换机 此类型交换机通过RoutingKey路由键将交换机和队列进行绑定消息被发送到exchange时需要根据消息的RoutingKey来进行匹配只将消息发送到完全匹配此RoutingKey的队列。 2.Fanout Exchange扇出交换机 此类型交换机会将消息分发给所有绑定了此交换机的队列此时RoutingKey无效。在Fanout类型交换机下发送一条消息无论RoutingKey是什么所有队列均可收到消息。 3.Topic Exchange主题交换机 此类型交换机与Direct类似也是需要通过RoutingKey路由键进行匹配分发区别在于Topic可以进行模糊匹配而Direct是完全匹配。 1.在Topic中将RoutingKey通过“.”来划分为多个部分 2.“*”代表一个部分 3.“#”代表0个或多个部分如果绑定的路由键为“#”时则接受所有消息因为路由键所有都匹配 4.Header Exchange头部交换机 Headers Exchange匹配AMQP消息的header而不是路由键此外headers交换机和direct交换机完全一致但由于它的性能差目前几乎用不到了。 在此类交换机中消费方指定的headers中必须包含一个“x-match”的键。该键的值有两个 1.x-match all表示所有的键值对都匹配才能接收到消息 2.x-match any表示只要有键值对匹配就能接受到消息
说说RabbitMQ的持久化机制
RabbitMQ的持久化是一个重要的功能它确保了即使在RabbitMQ服务器意外关闭或重启的情况下消息仍然能够得到保存和恢复。RabbitMQ的持久化包括三个方面交换器的持久化、队列的持久化和消息的持久化。 交换器的持久化是通过在声明交换器时指定Durability参数为durable实现的。如果交换器不设置持久化那么在RabbitMQ服务重启之后相关的交换器元数据会丢失但消息不会丢失只是不能将消息发送到这个交换器中。 队列的持久化也是通过在声明队列时指定Durability参数为durable实现的。如果队列不设置持久化在RabbitMQ服务重启之后相关队列的元数据和消息数据都会丢失。设置队列持久化可以确保队列本身的元数据不会因异常情况而丢失但并不能保证内部所存储的消息不会丢失。为了确保消息不会丢失需要将消息设置为持久化。 消息的持久化可以通过消息的投递模式来实现。将消息设置为持久化可以确保消息在RabbitMQ服务器意外关闭或重启后能够得到恢复。然而将所有消息都设置为持久化会严重影响RabbitMQ服务器的性能因为写入磁盘的速度比写入内存的速度慢得多。因此在选择是否要将消息持久化时需要在可靠性和吞吐量之间做一个权衡。
如何保证RabbitMQ的消息可靠性传输保证消息不丢失
在RabbitMQ的整个消息投递过程中有以下三种情况会存在消息丢失的问题
1.生产者把消息发送到RabbitMQ Server的过程中丢失 2.RabbitMQ Server收到消息后在持久化之前宕机导致数据丢失 3.消费端收到消息后还未来得及处理便宕机导致RabbitMQ Server认为这个消息已经签收这个消息就无法重复投递导致消息无法消费的问题。
所以只需要解决这三个角度的问题就能保证消息的可靠传输。 从生产者发送消息到Server端的角度来说RabbitMQ提供了一个Confirm的消息确认机制也就是说生产者发送的消息到Server端后如果消息处理成功Server端会返回客户端一个ack的消息那么客户端可以根据消息的处理结果来决定是否要对消息进行重新发送从而确保消息一定要到达到RabbitMQ Server端上 从Server端的角度来说可以开启消息的持久化机制也就是收到消息后将消息持久化到磁盘里面设置消息的持久化一般有两个步骤首先在创建Queue的时候设置为持久化然后在发送消息的时候把消息投递模式设置为持久化投递。虽然设置了持久化消息但是也有可能会出现问题比如消息刷新到磁盘上之前RabbitMQ的Server端就发生宕机这还是会导致消息丢失。为了确保万无一失需要结合Confirm消息确认机制来一起使用 从消费者的角度来看可以把消息的ack机制中的自动确认修改为手动确认将auto_ack参数设置为false也就是说消费端只有手动调用消息确认方法才表示这个消息已经被签收这种方式可能会造成消息的重复消费所以还需要考虑到幂等性的设计。
RabbitMQ中如何保证消息不被重复消费
保证消息不被重复消费实际上就是解决消息消费端幂等问题 幂等性指的是一条指令任意多次执行所产生的影响均与一次执行的影响相同。所以只要消费端具备了幂等性消息重复消费的问题就解决了。 实现消息幂等性可以采用以下两种方案 1.使用数据库的唯一约束实现幂等比如对于MQ中的消息设置一个唯一的消息id如果消费端多次消费就会触发数据库的唯一约束异常从而实现消息的幂等性。 2.使用redis中的setNX指令在MQ中为了避免MQ重复消费导致数据被多次修改消费端可以在接收到消息时把消息通过setNX写入到redis里面这样一来一旦消息被消费过就不会再次被消费。
RabbitMQ中如何解决消息堆积问题
在RabbitMQ中出现消息堆积问题的场景一般有以下几种 1.消息被消费方拒绝一般来说这种情况是出现在程序或是逻辑有问题的时候。 解决方法通过添加死信队列或是日志记录的方式避免消息重新入队 2.消费者消费消息的速度慢从而导致消息的堵塞堆积。 解决方法通过优化程序代码或建立消费者集群的方式增加消费者的消费能力。 3.队列容量不够也可能导致消息堆积。 解决方法增加队列的容量以容纳更多的待处理消息。
RabbitMQ如何保证消息的顺序消费
我们说的保证顺序消费说的是消费者消费信息的顺序。虽然Server端队列中的消息是顺序的但是由于多个消费者并发消费消息所以获取消息的速度不一样从而可能会导致消息的消费顺序出现问题。 想要解决顺序消费的问题通常的解决办法就是一个队列只有一个消费者这样就可以一个个消息按顺序处理但缺点就是并发能力下降无法并发消费消息这是个取舍的问题。 也可以在发送消息时使用一些标识符或分区键将消息分区并确保具有相同标识符的消息被发送到同一个队列。然后可以使用多个消费者每个消费者处理一个特定的分区从而保证了消息在特定分区内的顺序性。
RabbitMQ如何给消息设置过期时间
在RabbitMQ中存在2种方法设置消息的过期时间。第一种方法是通过对队列进行设置这种设置后该队列中所有的消息都存在相同的过期时间第二种方法是通过对消息本身进行设置那么每条消息的过期时间都不一样。如果同时使用这两种方法那么以过期时间较小的哪个数值为准。当消息达到过期时间还没有被消费那么该消息就成为了一个死信消息。 队列设置在队列中声明的时候使用x-message-ttl参数单位为 毫秒。 单个消息设置设置消息属性的expiration参数的值单位为 毫秒。
说说RabbitMQ的死信队列
当队列中的消息被拒绝、或者消息过期会变成死信死信可以被重新发布到另一个交换机这个交换机是死信交换机DLX,Dead Letter Exchange与DLX绑定的队列被称为死信队列。 出现死信的原因一般有以下几点1.消息被消费方拒绝消费方使用channel.basicNack或channel.basicReject并且此时requeue属性被设置为false2.消息超出过期时间超时3.消息总量超过了队列的最大长度
说说RabbitMQ的延迟队列
延迟队列存储的是延迟消息。延迟消息是指当消息被发布出去后并不立即投递给消费者而是在指定时间之后投递。例如在订单系统中订单有30秒的付款时间在订单超时之后再投递给消费者处理超时订单。 RabbitMQ没有直接支持延迟队列可以通过死信队列来实现。在死信队列中可以为普通交换机绑定多个消息队列假设绑定过期时间为5分钟10分钟和30分钟三个消息队列然后为每个消息队列设置DLX为每个DLX关联一个死信队列。 当消息过期后消息会被转存到对应的死信队列中然后投递给指定的消费者消费。