RabbitMQ基础知识总结
一、六大应用模式 1、简单模式 2、工作队列 3、远程过程调用(RPC) 图解流程说明: (1)当客户端启动的时候,作为生产者的客户端将创建一个匿名独享的回调队列。 (2)在 RPC 请求中,客户端(生产者)将带有两个属性的消息(一个是设置回调队列的 reply_to 属性,另一个是设置唯一值的 correlation_id 属性)发送到一个RPC_QUEUE队列中。 (3)服务器(此时服务器端是消费者)监听这个RPC_QUEUE队列。当这个队列中有请求(消息)出现的时候,服务器将接收并处理完这个请求(消息),并且将处理结果扔进 reply_to 字段指定的队列。 (4)客户端(这时候客户端就是消费者了)监听回调队列里的数据。当有消息出现的时候,它会检查 correlation_id 属性。如果此属性的值与请求匹配,则作为一次正常的服务器响应去处理了
四种Exchanges类型:direct, topic, headers and fanout 4、发布订阅(交换机类型:fanout) 5、路由(交换机类型:direct) 6、主题(交换机类型:topic) 二、RabbitMQ的消息确认机制 1、生产端发送消息确认:分为事务和实现confirm机制。不过一般不使用事务,性能消耗太大。 2、消费端消费确认: 消费端消息的确认分为:自动确认(默认)、手动确认、不确认 AcknowledgeMode.NONE:不确认 AcknowledgeMode.AUTO:自动确认 AcknowledgeMode.MANUAL:手动确认 (1)消费成功手动确认方法: void basicAck(long deliveryTag, boolean multiple) throws IOException; deliveryTag:该消息的index multiple:是否批量确认。true:将一次性ack所有小于deliveryTag的消息。 消费者成功处理消息后,手动调用channel.basicAck(message.getMessageProperties().getDeliveryTag(), false)方法对消息进行消费确认。
(2)消费失败手动确认方法: void basicNack(long deliveryTag, boolean multiple, boolean requeue) throws IOException; deliveryTag:该消息的index。 multiple:是否批量. true:将一次性拒绝所有小于deliveryTag的消息。 requeue:被拒绝的是否重新入队列。
void basicReject(long deliveryTag, boolean requeue) throws IOException; deliveryTag:该消息的index。 requeue:被拒绝的是否重新入队列。 channel.basicNack 方法与 channel.basicReject 方法区别在于basicNack可以批量拒绝多条消息,而basicReject一次只能拒绝一条消息。 三、消费端消费模式 push:broker主动将消息推送给订阅队列的消费者 pull:消费者调用channel.basicGet方法,主动从队列中拉取消息 两种模式都可进行消息确认设置:自动确认(autoAck为true)、手动确认(autoAck为false),当这个参数为true时, RabbitMQ服务器在发送消息到socket插口后, 就会将消息移除,consumer不会对消息进行确认。
两种模式的优缺点:
- push模式的优缺点
push优点: 服务端主动推送给客户端,及时性很高 push缺点: 1.当客户端消费能力远低于服务端生产能力,那么一旦服务端推送大量消息到客户端时,就会导致客户端消息堆积,处理缓慢,甚至服务崩溃。(那么如何解决这个问题呢?需要mq提供流控制,也就是依据客户端消费能力做流控。比如rabbitmq设置Qos,限制消费数量。) 2.服务端需要维护每次传输状态,以防消息传递失败进行重试。 - pull模式的优缺点
pull模式优点: 1.客户端可以依据自己的消费能力进行消费 2.传输失败时不需要重试,反正数据还在服务端。 pull模式缺点: 1.主动到服务端拉取消息。这个拉取消息的间隔需要设置好,不太好设置。间隔太短,对服务器请求压力过大。间隔时间过长,那么必然会造成一部分数据的延迟。(也有一些解决方案,间隔时间指数级增长,5ms,10ms,20ms,40ms,80ms。。。然后再回到5ms,一定程度上解决,但是如果在41ms时来了数据,那么到80ms就有40ms左右的时间延迟。另外在腾讯的CMQ里有一套长轮询的解决方案,就是取数据时要是没有数据可消费,不是直接返回而是连接等待,一直有数据来了再返回) - push和pull模式不同适用场景 对于服务端生产消息数据比较大时,而消费端处理比较复杂,消费能力相对较低时,这种情况就适用pull模式。
对于数据实时性要求高的场景,就比较适用与push模式。
当使用push并且为手动确认方式时,可以使用basicQos让RabbitMQ一次投递多个消息到consumer, 实现消息的预取(prefetch)。如果consumer设置了自动确认, basicQos API不会起作用, 其没有任何意义。具体看博客 RabbitMQ的consumer预取(prefetch)行为.
本博客参考文章: Rabbitmq六大应用模式. Rabbitmq的六大工作模式机制. RabbitMQ的消息确认机制. 消息中间件push和pull模式. RabbitMQ的consumer预取(prefetch)行为.
|