RabbitMq完全知识整理

 1. RabbitMQ

1.1. 分布式开发遇到的问题

随着微服务架构的流行,MQ成了解决微服务之间问题的常用工具。

以电商应用为例,应用中有订单系统、库存系统、物流系统、支付系统。用户创建订单后,如果耦合调用库存系统、物流系统、支付系统,任何一个子系统出了故障,都会造成下单操作异常。

当转变成基于消息队列的方式后,系统间调用的问题会减少很多,比如物流系统因为发生故障,需要几分钟来修复。在这几分钟的时间里,物流系统要处理的内存被缓存在消息队列中,用户的下单操作可以正常完成。当物流系统恢复后,继续处理订单信息即可,中单用户感受不到物流系统的故障。提升系统的可用性。

1.2. 消息队列(MQ)

1.2.1. 什么是消息队列

消息队列,即MQ,Message Queue。

**消息传递:**指的是程序之间通过消息发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。

**排队:**指的是应用程序通过队列来通信。

业务场景说明:

消息队列在大型电子商务类网站,如京东、淘宝、去哪儿等网站有着深入的应用,为什么会产生消息队列?有几个原因:

不同进程(process)之间传递消息时,两个进程之间耦合程度过高,改动一个进程,引发必须修改另一个进程,为了隔离这两个进程,在两进程间抽离出一层(一个模块),所有两进程之间传递的消息,都必须通过消息队列来传递,单独修改某一个进程,不会影响另一个;

不同进程(process)之间传递消息时,为了实现标准化,将消息的格式规范化了,并且,某一个进程接受的消息太多,一下子无法处理完,并且也有先后顺序,必须对收到的消息进行排队,因此诞生了事实上的消息队列;

消息队列是典型的:生产者、消费者模型。生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息。因为消息的生产和消费都是异步的,而且只关心消息的发送和接收,没有业务逻辑的侵入,这样就实现了生产者和消费者的解耦。

结合前面所说的问题:

商品服务对商品增删改以后,无需去操作索引库,只是发送一条消息,也不关心消息被谁接收。

搜索服务服务接收消息,去处理索引库。

如果以后有其它系统也依赖商品服务的数据,同样监听消息即可,商品服务无需任何代码修改。

1.2.2 消息队列主要作用

1、异步处理

串行和并行:

(1) 串行方式:

将注册信息写入数据库后,发送注册邮件,再发送注册短信,以上三个任务全部完成后才返回给客户端。 这有一个问题是,邮件,短信并不是必须的,它只是一个通知,而这种做法让客户端等待没有必要等待的东西。

(2) 并行方式:

将注册信息写入数据库后,发送邮件的同时,发送短信,以上三个任务完成后,返回给客户端,并行的方式能提高处理的时间。

传统模式的缺点:

一些非必要的业务逻辑以同步(串行)的方式运行,太耗费时间。

中间件模式的的优点:

将消息写入消息队列,非必要的业务逻辑以异步的方式运行,加快响应速度

2、解耦服务

传统模式的缺点:

系统间耦合性太强,系统A在代码中直接调用系统B和系统C的代码,如果将来D系统接入,系统A还需要修改代码,过于麻烦!

消息中间件模式的的优点:

将消息写入消息队列,需要消息的系统自己从消息队列中订阅,从而系统A不需要做任何修改。

3、流量削峰(削峰填谷)

流量削峰一般在秒杀活动中应用广泛

场景: 秒杀活动,一般会因为流量过大,导致应用挂掉,为了解决这个问题,一般在应用前端加入消息队列。

传统模式

如订单系统,在下单的时候就会往数据库写数据。但是数据库只能支撑每秒1000左右的并发写入,并发量再高就容易宕机。低峰期的时候并发也就100多个,但是在高峰期时候,并发量会突然激增到5000以上,这个时候数据库肯定卡死了。

中间件模式

消息被MQ保存起来了,然后系统就可以按照自己的消费能力来消费,比如每秒1000个数据,这样慢慢写入数据库,这样就不会卡死数据库了。

1.2.2. AMQP和JMS

MQ是消息通信的模型,并不是具体实现。现在实现MQ的有两种主流方式:AMQP、JMS。

两者间的区别和联系:

JMS是定义了统一的接口,来对消息操作进行统一;AMQP是通过规定协议来统一数据交互的格式

JMS限定了必须使用Java语言;AMQP只是协议,不规定实现方式,因此是跨语言的。

JMS规定了两种消息模型;而AMQP的消息模型更加丰富

1.2.3. 常见MQ产品

ActiveMQ:基于JMS

RabbitMQ:基于AMQP协议,erlang语言开发,稳定性好

RocketMQ:基于JMS,阿里巴巴产品,目前交由Apache基金会

Kafka:分布式消息系统,高吞吐量

1.2.4. RabbitMQ

RabbitMQ由erlang语言开发,是基于AMQP的一款消息管理系统

官网: http://www.rabbitmq.com/

官方教程:http://www.rabbitmq.com/getstarted.html

RabbitMQ 基础架构如下图:

**Broker:**接收和分发消息的应用,RabbitMQ Server就是 Message Broker

**Virtual host:**出于多租户和安全因素设计的,把 AMQP 的基本组件划分到一个虚拟的分组中,类似于网络中的 namespace 概念。当多个不同的用户使用同一个 RabbitMQ server 提供的服务时,可以划分出多个vhost,每个用户在自己的 vhost 创建 exchange/queue 等

**Connection:**publisher/consumer 和 broker 之间的 TCP 连接

**Channel:**如果每一次访问 RabbitMQ 都建立一个 Connection,在消息量大的时候建立 TCP Connection的开销将是巨大的,效率也较低。Channel 是在 connection 内部建立的逻辑连接,如果应用程序支持多线程,通常每个thread创建单独的 channel 进行通讯,AMQP method 包含了channel id 帮助客户端和message broker 识别 channel,所以 channel 之间是完全隔离的。Channel 作为轻量级的 Connection 极大减少了操作系统建立 TCP connection 的开销

**Exchange:**message 到达 broker 的第一站,根据分发规则,匹配查询表中的 routing key,分发消息到queue 中去。常用的类型有:direct (point-to-point), topic (publish-subscribe) and fanout (multicast)

**Queue:**消息最终被送到这里等待 consumer 取走

**Binding:**exchange 和 queue 之间的虚拟连接,binding 中可以包含 routing key。Binding 信息被保存到 exchange 中的查询表中,用于 message 的分发依据

1.3. 下载和安装

1.3.1. 下载

官网下载地址:http://www.rabbitmq.com/download.html

1.3.2. 安装

1. 方式1-docker中安装

下载镜像:docker pull rabbitmq:management

创建实例并启动:

docker run -d --name rabbitmq --publish 5671:5671 \

--publish 5672:5672 --publish 4369:4369 --publish 25672:25672 --publish 15671:15671 --publish 15672:15672 \

rabbitmq:management

注:

4369 – erlang发现口

5672 --client端通信口

15672 – 管理界面ui端口

25672 – server间内部通信口

2. 方式2-安装包安装
2.1 安装Erlang、Socat、RabbitMQ

拷贝课件中的安装包到虚拟机/opt目录下

执行安装命令:

rpm -ivh erlang-21.3.8.9-1.el7.x86_64.rpm

rpm -ivh socat-1.7.3.2-1.el6.lux.x86_64.rpm

rpm -ivh  rabbitmq-server-3.8.1-1.el7.noarch.rpm

#如果rabbitmq安装报错,在线安装socat

yum install -y socat

安装成功后rabbitmq命令存放在:/usr/lib/rabbitmq/lib/rabbitmq_server-3.8.1/sbin

2.2 启用管理插件

rabbitmq-plugins enable rabbitmq_management

2.3 RabbitMQ启停命令

# 第一次启动时会比较慢

systemctl start rabbitmq-server.service

systemctl status rabbitmq-server.service

systemctl restart rabbitmq-server.service

systemctl stop rabbitmq-server.service

2.4 查看进程

ps -ef | grep rabbitmq

rabbitmq启动时会监听三个端口号:

​ 5672: 其他程序和rabbitmq交互的端口[比如:java程序需要使用rabbitmq,就和此端口建立连接]

​ 15672:rabbitmq的后台管理系统的端口号[rabbitmq的客户端]

​ 25672:集群环境搭建的端口号

1.3.3. 测试

在web浏览器中输入地址:http://虚拟机ip:15672/

输入默认账号: guest : guest,默认不允许远程连接

解决:

增加管理员账号:

rabbitmqctl add_user admin admin

如果新增慢,然后报错新增失败,解决方案:

//查询当前主机的名称

cat /etc/hostname

//将主机名称和本机的ip 127.0.0.1绑定映射存到hosts文件中

vim /etc/hosts

127.0.0.1    查询到的主机名称

//然后再次添加用户

rabbitmqctl add_user admin admin

给账号分配角色:

# 角色:

# 1、超级管理员(administrator):所有权限

# 2、监控者(monitoring): 登录控制台、查看mq信息权限

# 3、策略制定者(policym

<think>好的,我现在需要回答用户关于RabbitMQ的工作原理以及它是否基于TCP连接的问题。首先,我需要回忆一下RabbitMQ的基础知识RabbitMQ是一个消息代理,实现了AMQP协议,用于在分布式系统中传递消息。用户特别问到是否基于TCP,这点我记得AMQP协议通常是基于TCP的,但需要确认细节。 接下来,我应该参考用户提供的引用内容。引用[1]提到RabbitMQ是AMQP的实现,而引用[2]也提到AMQP的环境搭建,可能需要TCP连接。引用[3]和[4]展示了Java连接RabbitMQ的代码和配置,其中host和port的设置应该涉及到网络连接,通常是TCP的端口,比如5672是RabbitMQ的默认端口。 然后,我需要整理这些信息。首先,RabbitMQ的工作原理包括生产者发送消息到交换器,交换器根据类型和路由键将消息路由到队列,消费者从队列接收消息。这部分需要简明扼要地解释,同时结合引用中的内容,比如交换器类型(Direct、Fanout等)来自引用[2]。 关于TCP连接的部分,需要明确AMQP协议确实运行在TCP之上,使用可靠的传输层保证消息传递。RabbitMQ默认使用5672端口,这也是TCP端口。引用[4]中的配置示例中的host和port设置也暗示了TCP连接的必要性。 此外,可以提到AMQP协议的特性,如持久化、确认机制,以及如何通过TCP保证可靠性。同时,引用[3]中的Java代码使用RabbitListener监听队列,这背后也是通过TCP连接与RabbitMQ服务器通信。 需要确保回答结构清晰,分点说明工作原理和TCP连接的部分。可能还需要指出其他协议的支持,比如MQTT或STOMP,但默认是AMQP over TCP。 最后,生成相关问题,考虑用户可能对协议细节、端口配置、不同协议对比等感兴趣的问题。</think>RabbitMQ的工作原理及TCP连接特性分析如下: ### 一、RabbitMQ核心工作原理 1. **AMQP协议基础** RabbitMQ基于高级消息队列协议(AMQP 0-9-1)实现,该协议定义了消息格式、交换器类型和路由规则。生产者通过$channel$将消息发送到$exchange$,交换器根据绑定规则(binding key)和路由键(routing key)将消息分发到队列,最后由消费者订阅队列获取消息[^1]。 2. **核心组件交互流程** ```plaintext 生产者 → 交换器(Exchange) → 队列(Queue) → 消费者 ``` - **交换器类型**:包括$Direct$(精准匹配)、$Fanout$(广播)、$Topic$(模式匹配)和$Header$(头信息匹配)[^2] - **消息确认机制**:消费者处理消息后需发送$ack$确认,确保可靠性传输[^4] 3. **Java连接示例** 如引用[3]所示,通过$@RabbitListener$注解监听队列,底层通过TCP连接与RabbitMQ服务器通信: ```java @RabbitListener(queues = "QUEUE_NAME") public void handleMessage(String msg) { // 消息处理逻辑 } ``` ### 二、TCP连接机制详解 1. **协议层实现** RabbitMQ的AMQP协议**完全基于TCP连接**,默认使用$5672$端口。TCP提供可靠传输保障,确保消息不丢失、不重复[^2]。 2. **连接管理特征** - **长连接复用**:通过$channel$复用单个TCP连接,减少资源消耗 - **心跳检测**:自动维持连接活性(默认心跳间隔580秒) - **加密支持**:可通过TLS加密TCP连接(使用$5671$端口) 3. **重试机制配置** 如引用[4]所示,Spring配置支持TCP连接异常时的自动重试: ```properties spring.rabbitmq.listener.simple.retry.enabled=true spring.rabbitmq.listener.simple.retry.max-attempts=3 ``` ### 三、特殊协议支持说明 虽然默认使用AMQP over TCP,但RabbitMQ通过插件支持其他协议: - **MQTT**:适用于物联网场景 - **STOMP**:简单文本协议 - **HTTP**:通过Web STOMP插件 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

开发小牛牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值