com.rabbitmq:amqp-client

本文详细介绍了RabbitMQ的安装配置、AMQP协议的工作原理、消息的生产消费流程,包括交换机类型、队列操作、死信、延迟和优先级队列。此外,还深入探讨了消费端的消息确认与拒绝机制,以及消息的分发、顺序性和传输保障。最后,讲解了队列结构、存储机制和流量控制,帮助读者全面理解RabbitMQ的运作机制。

目录

安装与配置

AMQP协议介绍

客户端开发(连接、交换机、队列、生产/消费消息)

基础概念

交换机类型

RabbitMQ运转流程

消费消息:推模式和拉模式

消费端消息确认与拒绝

队列类型(死信、延迟、优先级队列)

死信队列

 延迟队列

 优先级队列

持久化与生产者确认

消息分发、顺序、传输保障

消息分发

消息顺序性

消息传输保障

队列结构、流量控制

存储机制

队列结构

流量控制


安装配置

  1. Downloading and Installing RabbitMQ :https://www.rabbitmq.com/download.html
  2. RabbitMQ中文文档:RabbitMQ中文文档 · RabbitMQ in Chinese
  3. 教程:https://www.rabbitmq.com/getstarted.html
  4. 常用指令
启动 rabbitmqctl -server -detached
查看是否启动成功 rabbitmqctl status
查看集群信息 rabbitmqctl cluster_status
创建用户 rabbitmqctl add_user username psd
设置用户所有权限 rabbitmqctl set_permissions -p/username ". *" ". *" ". *"
设置用户权限 rabbitmqctl [--node ] [--longnames] [--quiet] set_permissions [--vhost ]
命令帮助 rabbitmqctl help

AMQP协议介绍

        消息队列的运转过程如下图所示,首先生产者将业务方数据进行可能的包装,之后封装 成消息,发送(AMQP协议里这个动作对应的命令为Basic.Publish)到Broker中。消费者订阅并接收消息(AMQP协议里这个动作对应的命令为 Basic.Consume或者Basic.Get),经过可能的解包处理得到原始的数据,之后再进行业务处理逻辑。这个业务处理逻辑并不一定需要和接收消息的逻辑使用同一个线程。 消费者进程可以使用一个线程去接收消息, 存入到 内存中,比如使用Java中的BlockingQueue。业务处理逻辑使用另一个线程从内存中读取数据,这样可以将应用进一步解耦,提高整个应用的处理效率。

        AMQP协议本身包括三层:

  1. Module Layer:位于协议最高层,主要定义了一些共客户端调用的命令,客户端可以利用这些命令实现自己的业务逻辑。如:Queue.Declare命令用于声明队列。
  2. Session Layer:位于中间层,主要负责将客户端命令发送给服务器,再将服务器端的应答返回给客户端,主要为客户端与服务器之间的通信提供可靠性同步机制和错误处理。
  3. Transport Layer:位于最底层,主要传输二进制数据流,提供帧的处理、信道复用、错误检测和数据表示等。
AMQP生产者流转过程  AMQP 消费者流转过程(推模式)

 更多信息可以在AMQP官网下下载,RabbitMQ使用的是0-9-1版。

客户端开发(连接、交换机、队列、生产/消费消息)

基础概念

  1. 生产者/消费者:消息的发送方和消费方。消息一般包括消息体和标签两部分。消息体一般是带有业务逻辑的数据,标签一般用来描述消息。消费时,只能消费消息的消息体。消息在路由过程中,消息标签会丢弃,只有消息体才能存入队列中。
  2. 队列:用于存储消息,当多个消费者订阅统一队列时,默认采用平均分摊(轮询)规则处理消息。
  3. 交换机:RabbitMQ中,生产者将消息发送到交换机,然后再通过路由键(Routing Key)将消息路由到与绑定建(Binding Key)匹配的队列中。点对点模式时,可以直接发送给队列。
  4. 路由键:生产者将消息发送给交换机时,一般会指定一个RoutingKey,用来指定这个消息的路由规则。
  5. 绑定键:通过绑定键把交换机与队列关联起来。结合生产者指定的RoutingKey,才可以正确的将消息路由到队列。

        生产者将消息发送给交换器时, 需要一个 RoutingKey,当BindingKey和RoutingKey相 匹配时,消息会被路由到对应的队列中。 在绑定多个队列到同一个交换器的时候,这些绑定允许使用相同的BindingKey。BindingKey并不是在所有的情况下都生效,它依赖于交换器 类型,比如fanout类型的交换器就会无视 BindingKey,而是将消息路由到所有绑定到该交换器的队列中。

交换机类型

  1. fanout:将消息路由到所有绑定到该交换器的队列中
  2. direct:把消息路由到BindingKey和RoutingKey完全匹配的队列中
  3. topic规则:
  • RoutingKey为一个点号“.”分隔的字符串(被点号“.”分隔开的每一段独立的字符串称为一个单词), 如“com. rabbitmq. client”、“java. util. concurrent”、“com. hidden. client”;
  •  BindingKey和RoutingKey一样也是点号“.”分隔的字符串;
  • BindingKey中可以存在两种特殊字符串“*”和“#”,用于做模糊匹配,其中“*”用于匹配一个单词,“#”用于匹配多规格单词(可以是零个)。
  • 举例:

(1) 路由键为“com. rabbitmq. client”的消息会同时路由到Queue1和Queue2;

(2) 路由键为“com. hidden. client”的消息只会路由到Queue2 中;

(3) 路由键为“com. hidden. demo”的消息只会路由到Queue2 中;

(4) 路由键为“java. rabbitmq. demo”的消息只会路由到Queue1中;

(5) 路由键为“java. util. concurrent”的消息将会被丢弃或者返回给生产者(需要设置mandatory参数),因为它没有匹配任何路由键。

RabbitMQ运转流程

  • 生产者生产消息过程:

(1) 生产者连接到RabbitMQ Broker,建立一个连接(Connection),开启一个信道(Channel)。

ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost(HOST);
connectionFactory.setPort(PORT);
/**
 * 如果配置有用户名密码以及vhost,则配置即可。
 */
connectionFactory.setUsername(USERNAME);
connectionFactory.setPassword(PASSWORD);
connectionFactory.setVirtualHost(VIRTUALHOST);
//使用uri方式
//connectionFactory.setUri(“qmqp://userName:password@ipAddress:protNumber/virtualHost”);
Connection connection = ConnectionUtils.getConnection();
Channel channel = connection.createChannel();

Connection可以用来创建多个Channel实例,但是Channel实例不能在线程间共享,多线程共享Channel实例是线程不安全的,应用程序应该为每个线程开辟一个channel。

慎用Connection或者Channel的isOpen方法检测是否处于开启状态。

(2) 生产者声明一个交换器,并设置相关属性,比如交换机类型是否持久化等。

channel.exchangeDeclare("exchange.confirm", "direct", true, false, null);
  • 函数Exchange.DeclareOk exchangeDeclare参数介绍,有多个重载方法:

        (1) String exchange:交换机名称

        (2) String type:交换机类型(fanout/direct/topic)

        (3) boolean durable:是否持久化;持久化后服务器重启不丢失相关信息

        (4) boolean autoDelete:是否自动删除,自动删除的前提是至少有一个队列或者交换器与这个交换器绑定,之后所有与这个交换器绑定的队列或者交换器都与此解绑。

        (5) boolean Internal:设置是否是内置的。如果设置为true,则表示是内置的交换器,客户端程序无法直接发送消息到这个交换器中,只能通过交换器路由到交换器这种方式。

        (6) Map<String,Object> arguments:其他结构化参数

  • void exchangeDeclareNoWait方法,多了一个nowait参数,不建议使用。
  • Exchange.DeclareOk exchangeDeclarePassive(String name)方法,主要用来检测交换机是否存在,存在正常返回,不存在抛出异常。
  • 其他方法可以在Channel接口中查看。

(3) 生产者声明一个队列并设置相关属性,比如是否排他、是否持久化、是否自动删除等。


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值