相关概念:
rabbitmq就是一个生产者、消费者模式,主要用来接收,存储,转发消息;从计算机模型来看,rabbitmq更像一种交换机模型。
- Producer:生产者,消息投递的一方;消息包括2个部分,消息体(payload)和标签(label)
- consumer:消费者,消息接收方;
- broker:消息中间件的服务节点。
消息发送的流程
- queue :队列,rabbitmq内部对象,存储消息;
- exchange:交换器
- routingKey:路由键,生产者将消息发送给交换机是,一般需要指定路由键
- binding:绑定
- 交换器的类型:fanout,direct,topic, headers
rabbitMq运转流程:
- 生产者发送消息
- 生产者连接到一个rabbitMq broker,建立一个connection,开启一个信道;
- 生产者申明一个一个交换器,并设置相关属性,比如交换器类型、是否持久化等;
- 生产者声明一个队列并设置相关属性,比如是否排他、是否持久化、是否自动删除等;
- 生产者通过路由键将队列和交换器绑定起来;
- 生产者发送消息值RabbitMq broker,其中包含路由键、交换器等信息;
- 相对应的交换器根据路由键查找对应的队列;
- 如果找到,则将生产者发送的消息存储到队列中;
- 如果没有找到,则根据生产者的配置属性返还该生产者还是选择丢弃;
- 关闭信道、关闭连接。
- 消费者接收消息
- 消费者连接到一个rabbitMq broker,建立一个connection,开启一个信道;
- 消费者申明一个一个交换器,并设置相关属性,比如交换器类型、是否持久化等;
- 等待rabbitmq broker回应投递的相对列中的消息,消费者接收消息;
- 消费者确认接收到的消息(ack);
- RabbitMq从队列删除已经确认接收的消息;
- 关闭信道、关闭连接。
AMQP协议介绍
amqp协议包括三层:
- module layer:协议最高层,主要定义协议的客户端调用命令,;
- session layer:中间层,主要负责将客户端的命令发送给服务器,再将服务端的消息发送给客户端,主要为客户端与服务器之间的通信提供可靠性同步机制和错误处理。
- transport layer:位于最底层。主要传输二进制数据流 ,提供帧的处理、信道复用、错误检测和数据表示等。
当客户端与 Broker 建立连接的时候,会调用 factory.newConnection 方法,这个方法会进一步封装成 Protocol Header 0-9-1 的报文头发送给 Broker ,以此通知 Broker 本次交互采用的是 AMQPO-9-1 协议,紧接着 Broker 返回 Connection.Start 来建立连接,在连接的过程 中涉及 Connection.Start/.Start-OK 、 Connection.Tune/.Tune-Ok , Connection.Open/ .Open-Ok 这 6 个命令的交互 。当客户端调用 connection .createChannel 方法准备开启 信道的时候,其包装Channel.Open命令发送给Broker 等待 Channel.Open-Ok 命令 。
当客户端发送消息的时候,需要调用 channel . basicPublish 方法,对应的 AQMP 命令为 Basic.Publish ,注意这个命令和前面涉及的命令略有不同,这个命令还包含了 Content Header 和 Content Body .当客户端发送完消息需要关闭资源时,涉及 Channel.Close/.Close-Ok 与Connection.Close/.Close-Ok 的命令交互
消费者客户端同样需要与 Broker 建立连接,与生产者客户端一样,协议交互同样涉及Connection.Start/ . Start-Ok 、Connection.Tune/.Tune-Ok 和 Connection.Open/ . Open-Ok 等.
紧接着也少不了在 Connection 之上建立 Channe l,和生产者客户端一样,协议涉及Channel . Open/Open-Ok。
如果在消费之前调用了 channel . basicQos(int prefetchCount) 的方法来设置消费者客户端最大能"保持"的未确认的消息数,那么协议流转会涉及 Basic.Qos/.Qos-Ok 这两个 AMQP 命令。
在真正消费之前,消费者客户端需要向 Broker 发送 Basic.Consume 命令(即调用channel.basicConsume 方法〉将 Channel 置为接收模式,之后 Broker 回执Basic . Consume - Ok 以告诉消费者客户端准备好消费消息。紧接着 Broker 向消费者客户端推
送 (Push) 消息,即 Basic.Deliver 命令,有意思的是这个和 Basic.Publish 命令一样会携带 Content Header 和 Content Body 0
消费者接收到消息并正确消费之后,向 Broker 发送确认,即 Basic.Ack 命令。在消费者停止消费的时候,主动关闭连接,这点和生产者 一 样,涉及Channel . Close/ . Close-Ok 手口 Connection.Close/ . Close-Ok 。