网站icp备案 技术负责人,帝国cms7.0模板 绿色企业网站模板(整站带数据),唐山专业做网站,网站建设合同概念一#xff1a;
在互联网行业#xff0c;许多公司喜欢用动物命名产品或作为公司的 Logo 和吉祥物#xff0c;比如腾讯的企鹅、京东的狗、美团的袋鼠、携程的海豚#xff0c;而阿里更是凭借蚂蚁、飞猪、天猫、菜鸟、闲鱼、盒马等#xff0c;打造了一座“动物园”。Rabbit
在互联网行业许多公司喜欢用动物命名产品或作为公司的 Logo 和吉祥物比如腾讯的企鹅、京东的狗、美团的袋鼠、携程的海豚而阿里更是凭借蚂蚁、飞猪、天猫、菜鸟、闲鱼、盒马等打造了一座“动物园”。Rabbit兔子也是一家公司的名字其产品 RabbitMQ 是一个消息队列Message QueueMQ服务实现了 AMQP高级消息队列协议并成为当前主流的消息中间件之一。
1.1 什么是 MQ
MQMessage Queue消息队列本质上是一个队列遵循 FIFO先入先出原则只不过队列中存放的是消息message。消息可以非常简单比如仅包含文本字符串或 JSON 格式也可以较为复杂例如内嵌对象。MQ 通常用于分布式系统之间的通信而系统之间的调用一般有两种方式
通信方式描述同步通信数据从一端发出后直接调用对方的服务数据立即传递到另一端实现实时响应。异步通信数据从一端发出后先进入一个容器进行临时存储达到某种条件后再由容器转发至另一端。容器的一种具体实现就是 MQ消息队列。 1.2 MQ 的作用
RabbitMQ 是一种 MQ 的实现其主要功能是接收和转发消息。在不同的应用场景中MQ 可以发挥多种作用。
场景描述异步解耦在业务流程中对于一些耗时但无需即时返回结果的操作可以通过 MQ 异步化处理。例如用户注册后发送短信或邮件通知可以作为异步任务不必等待这些操作完成再返回注册成功结果。流量削峰在流量激增时应用仍需保持正常运行而直接为峰值流量配置资源会造成浪费。MQ 可通过流量削峰功能将请求排队系统根据自身处理能力逐步处理。例如秒杀或促销活动中MQ 可以缓解突发流量压力防止系统崩溃。消息分发当多个系统需要对同一数据做出响应时MQ 可用于消息分发。例如支付成功后支付系统向 MQ 发送消息其他订阅该消息的系统可以获取更新无需轮询数据库。延迟通知在需要延迟发送通知的场景中MQ 提供延迟消息功能。例如在电商平台中如果用户下单后未在指定时间内支付可以通过延迟队列在超时后自动取消订单。
1.3 为什么学习 RabbitMQ
目前业界有多种 MQ 产品可供选择例如 RabbitMQ、RocketMQ、ActiveMQ、Kafka 和 ZeroMQ 等甚至也有直接使用 Redis 作为消息队列的案例。这些消息队列各有侧重没有绝对的优劣之分只有适不适合。在实际选型时需要根据自身需求和 MQ 产品的特点进行综合考量。
产品描述KafkaKafka 最初用于日志收集和传输追求高吞吐量性能卓越单机吞吐量可达十万级。其在日志领域功能简单且成熟主要支持基础的 MQ 功能是日志采集需求的首选。RocketMQRocketMQ 由阿里巴巴开源并捐赠给 Apache使用 Java 开发。借鉴了 Kafka 的设计并进行了优化经过多年双十一场景的验证在可用性、可靠性和稳定性方面表现出色适用于高可靠性和高并发场景如互联网金融领域。但其客户端语言支持较少社区活跃度一般。RabbitMQRabbitMQ 使用 Erlang 开发MQ 功能完备几乎支持所有主流语言且开源提供的管理界面友好。其性能较好吞吐量达万级社区活跃度高适合中小型公司尤其是在数据量和并发量不大的场景中使用。
由于 RabbitMQ 综合能力较强且我们的项目并非超高并发对 RabbitMQ 社区的成熟度和管理界面的友好性需求较高因此接下来主要学习 RabbitMQ 的使用。
二 RabbitMQ 核心概念 RabbitMQ是⼀个消息中间件也是⼀个⽣产者消费者模型它负责接收、存储并转发消息.界面上的导航栏分为 6 部分每部分都有其特定的功能含义。在深入了解之前我们先来看看 RabbitMQ 的工作流程以便更好地理解各部分的作用。 2.1 Producer 和 Consumer
生产者Producer负责创建消息并将其发布到 RabbitMQ 中。在实际应用中消息通常是具有一定业务逻辑结构的数据例如 JSON 字符串。消息可以附带标签RabbitMQ 会根据这些标签进行路由将消息发送给感兴趣的消费者Consumer。
消费者通过连接 RabbitMQ 服务器来消费消息。在消费过程中消息的标签会被丢弃消费者只接收消息内容并不会知道消息的生产者是谁也无需关心消息的来源。对于 RabbitMQ 而言一个 Broker 可以理解为一个 RabbitMQ 服务节点或实例大多数情况下可视为一台 RabbitMQ 服务器。
名称描述Producer生产者是 RabbitMQ Server 的客户端负责向 RabbitMQ 发送消息。Consumer消费者也是 RabbitMQ Server 的客户端负责从 RabbitMQ 接收消息。BrokerRabbitMQ Server 本身主要负责接收消息、存储消息并将消息分发给消费者。 2.2 Connection 和 Channel
名称描述Connection连接。客户端和 RabbitMQ 服务器之间的 TCP 连接是消息传递的基础负责传输客户端与服务器之间的所有数据和控制信息。Channel通道信道。Channel 是建立在 Connection 之上的抽象层在一个 TCP 连接上可以创建多个 Channel每个 Channel 是独立的虚拟连接。消息的发送和接收都是基于 Channel 的。
通道的主要作用是将消息的读写操作复用到同一个 TCP 连接上减少连接的建立和关闭开销从而提高系统性能。 2.3 Virtual host
Virtual host虚拟主机是一个逻辑概念用于为消息队列提供隔离机制。在 RabbitMQ 中一个 Broker Server 上可以包含多个 Virtual Host不同用户可以通过划分 vhost 来独立使用 RabbitMQ 服务在各自的 vhost 中创建和管理 exchange、queue 等资源。它类似于 MySQL 中的 “database” 概念是逻辑上的集合而非类似 VMware 那样的物理虚拟机。
2.4 Queue
Queue 是 RabbitMQ 的内部对象用于存储消息。多个消费者可以同时订阅同一个队列共同消费其中的消息。 2.5 Exchange
Exchange交换机是消息到达 RabbitMQ Broker 的第一站负责接收生产者发送的消息并根据特定的规则将这些消息路由到一个或多个队列中。交换机起到消息路由的作用通过其类型和规则来决定如何转发消息。类似于快递物流根据收件地址分派快递到不同的站点再由站点配送到收件人手中交换机的作用就相当于完成这一步的分配工作。 2.6 RabbitMQ 工作流程
在理解了上述概念之后我们可以通过回顾这张图进一步梳理 RabbitMQ 的工作流程。
Producer生产者生成一条消息。Producer 连接到 RabbitMQ Broker建立一个连接Connection并开启一个信道Channel。Producer 声明一个交换机Exchange用于路由消息。Producer 声明一个队列Queue用于存储消息。Producer 将消息发送到 RabbitMQ Broker。RabbitMQ Broker 接收消息并将其存入相应的队列Queue。如果找不到对应的队列则根据生产者的配置选择丢弃消息或退回给生产者。
RabbitMQ 核心概念对应的物流公司角色Broker类似物流公司的总部负责协调和管理所有物流站点确保包裹能够安全、高效地送达。Virtual Host类似物流公司为不同客户或业务部门划分的独立运营中心。每个运营中心都有自己的仓库Queue、分拣规则Exchange和运输路线Connection 和 Channel以确保不同客户的包裹互不干扰并提供定制化服务。Exchange类似物流站点中的分拣中心。根据包裹上的标签决定包裹的目的地队列。不同类型的分拣中心可能有不同规则如按地址分拣或将包裹复制给多个收件人等。Queue类似物流站点中的仓库用于临时存放等待派送的包裹。每个仓库都有一名或多名快递员消费者负责从仓库中取出包裹并派送给最终的收件人。Connection类似快递员与快递站点之间的通信线路快递员通过该线路接收派送任务消息。Channel类似快递员在执行任务时使用的多个并行通信线路允许快递员同时处理多个任务。例如一边派送包裹一边接收新的派送任务。 2.7 AMQP
AMQPAdvanced Message Queuing Protocol高级消息队列协议定义了一套完整的消息交换功能包括交换器Exchange和队列Queue等组件。这些组件协同工作使生产者能够将消息发送到交换器随后由队列接收并存储等待消费者取用。此外AMQP 还定义了一个网络协议用于支持客户端应用与消息代理之间的交互通信。
RabbitMQ 是 AMQP 协议的实现使用 Erlang 语言开发。换句话说RabbitMQ 遵循 AMQP 的规范同时还支持其他协议如 STOMP 和 MQTT。由于 RabbitMQ 的模型结构与 AMQP 的模型结构一致它可以充分发挥 AMQP 的强大功能。 三web 界面操作
RabbitMQ 管理界面中的 Connections、Channels、Exchange 和 Queues 对应的概念与上述流程图中的内容一致。其中Overview 表示系统的概览视图Admin 则用于用户和权限管理。在操作 RabbitMQ 前需要先创建一个 Virtual Host。接下来我们将详细介绍具体的操作步骤。
3.1 用户相关操作
3.1.1 添加用户
点击 Admin - Add user 设置账号密码及权限 步骤描述①设置账号②设置密码③确认密码④设置权限Tags如 Admin、Monitoring、Policymaker 等权限标签
观察用户是否添加成功 3.1.2 删除用户
点击要删除的用户, 查看用户详情 在用户详情页面, 进行更新或删除操作 设置对虚拟机的操作权限 更新 / 删除用户
3.1.3 退出当前用户 3.2 虚拟主机相关操作
3.2.1 创建虚拟主机
在 Admin 标签页下点击右侧的 Virtual Hosts - Add a new virtual host然后设置虚拟主机的名称。 四 RabbitMQ 快速入门
引入依赖
dependencygroupIdcom.rabbitmq/groupIdartifactIdamqp-client/artifactIdversion5.7.3/version
/dependency编写生产者代码
public class RabbitProducer {public static void main(String[] args) throws Exception {// 1. 创建连接工厂ConnectionFactory factory new ConnectionFactory();// 2. 设置连接参数factory.setHost(110.41.51.65); // 设置主机地址默认值为localhostfactory.setPort(15673); // 设置端口号默认值为5672factory.setVirtualHost(bite); // 设置虚拟主机名称默认值为 /factory.setUsername(study); // 设置用户名默认值为guestfactory.setPassword(study); // 设置密码默认值为guest// 3. 创建连接Connection connection factory.newConnection();// 4. 创建通道Channel channel connection.createChannel();// 5. 声明队列/** 1. queue: 队列名称* 2. durable: 是否持久化true队列会持久化到磁盘MQ重启后队列仍在* 3. exclusive: 是否独占true队列只允许当前连接使用连接关闭后队列自动删除* 4. autoDelete: 是否自动删除true当队列中没有消息且没有消费者时自动删除* 5. arguments: 队列的其他参数如 TTL、消息长度限制等** 如果指定的队列不存在则会自动创建该队列如果队列已存在则使用已有队列。*/channel.queueDeclare(hello, true, false, false, null);// 6. 发送消息到队列/** 1. exchange: 交换机名称简单模式下使用默认的交换机* 2. routingKey: 路由键此处设置为队列名称决定消息发送到哪个队列* 3. props: 配置信息如消息的优先级、过期时间等可设为null* 4. body: 消息内容字节数组形式** 使用默认的交换机时routingKey 必须与队列名称一致才能正确路由消息到指定队列。*/String msg Hello World; // 消息内容channel.basicPublish(, hello, null, msg.getBytes()); // 发送消息System.out.println(msg 消息发送成功);// 7. 释放资源channel.close(); // 关闭通道connection.close(); // 关闭连接}
}编写消费者代码
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeUnit;public class RabbitmqConsumer {public static void main(String[] args) throws Exception {// 1. 创建连接工厂ConnectionFactory factory new ConnectionFactory();// 2. 设置连接参数factory.setHost(110.41.51.65); // 设置主机地址默认值为 localhostfactory.setPort(15673); // 设置端口号默认值为 5672factory.setVirtualHost(bite); // 设置虚拟主机名称默认值为 /factory.setUsername(study); // 设置用户名默认值为 guestfactory.setPassword(study); // 设置密码默认值为 guest// 3. 创建连接Connection connection factory.newConnection();// 4. 创建通道Channel channel connection.createChannel();// 5. 声明队列/** 1. queue: 队列名称* 2. durable: 是否持久化true队列会持久化到磁盘MQ 重启后队列仍在* 3. exclusive: 是否独占true队列只允许当前连接使用连接关闭后队列自动删除* 4. autoDelete: 是否自动删除true当队列中没有消息且没有消费者时自动删除* 5. arguments: 队列的其他参数如 TTL、消息长度限制等** 如果指定的队列不存在则会自动创建该队列如果队列已存在则使用已有队列。*/channel.queueDeclare(hello, true, false, false, null);// 6. 接收并消费消息/** 1. queue: 队列名称* 2. autoAck: 是否自动确认true消费者收到消息后自动告诉 MQ 消息已消费* 3. callback: 回调对象处理接收到的消息*/DefaultConsumer consumer new DefaultConsumer(channel) {/** 回调方法当收到消息后会自动执行该方法* 参数说明* 1. consumerTag: 消费者标签标识消费者* 2. envelope: 包含一些信息如交换机、路由键* 3. properties: 消息的配置信息* 4. body: 消息内容字节数组形式*/Overridepublic void handleDelivery(String consumerTag, Envelope envelope,AMQP.BasicProperties properties, byte[] body) throws IOException {System.out.println(接收到消息: new String(body)); // 打印接收到的消息}};// 开始消费消息channel.basicConsume(hello, true, consumer);// 等待回调函数执行完毕TimeUnit.SECONDS.sleep(5);// 7. 释放资源// 消费者是一个监听程序通常情况下不需要主动关闭资源如果需要手动关闭可以按照以下顺序// channel.close();// connection.close();}
}生产者和消费者使用的通道channel并不是同一个。当一个新的 RabbitMQ 节点启动时它会预先声明几个内置交换机其中默认的内置交换机名称为空字符串“”。生产者发送的消息可以根据队列名称直接路由到对应的队列。
如果有一个名为 “hello” 的队列生产者可以直接将消息发送到 “hello” 队列而消费者可以从 “hello” 队列中接收消息而无需关注交换机的存在。这种模式非常适合简单的应用场景尤其是生产者和消费者之间的一对一通信。