rabbitmq

1.消息服务概述、rabbitmq核心概念

消息服务概述:

大多数应用中,可通过消息服务中间件来提升系统异步通信,扩展解耦能力

两个重要概念:消息代理(message broker)和目的地(destination)。当消息发送者者发出消息后,将由消息代理接管,消息代理保证将消息传递至目的地

两种形式的目的地:

队列(queue):点对点的消息通信(point-to-point)

主题(topic):发布(publish)/订阅(subscribe)的消息通信

点对点式:消息发送者发送消息,消息代理将消息放在一个队列中,消息接收者从队列中获取内容,消息读取后移除队列。消息只有唯一的发送者和接收者。但接收者并未说明只能有1个。

发布订阅式:发送者发送消息到主题,多个订阅者(接收者)监听(订阅)这个主题,会在消息到达时同时收到消息

两种消息代理规范:

JMS(Java-Message-Service)Java消息服务:基于JVM消息代理的规范,ActiveMQ、HornetMQ是JMS实现

AMQP(Advanced Message Queuing Protocol)高级消息队列协议:消息代理规范,兼容JMS,RabbitMQ是AMQP的实现

spring支持:spring提供了对JMS的支持,spring-rabbit提供可对AMQP的支持,需要ConnectionFactory的实现来连接消息代理,提供JmsTemplate、RabbitTemplate来发送消息,

@JmsListenet、@RabbitListener在方法上监听消息代理发送的消息,@EnableJms、@EnableRabbit开启支持

消息服务可解决问题

异步处理:

示例场景:用户注册,注册成功之后给用户邮箱及短信发送注册成功,注册、发送邮件、发送短信分别耗时50ms

串行模式:注册->发送邮件->发送短信 共计耗时150ms

并行模式:注册->发送邮件、发送短信 共计耗时100ms

分析优化思路:邮件和短信只是一个通知,并非客户端所必须的,因此注册成功之后即可告知客户端注册成功,客户端没必要等着收到邮件和短信后才显示注册成功

消息队列:注册->消息队列->发送短信/发送邮件 共计耗时55ms.

引入消息队列后,用户响应时间即 写入数据库的时间+写入消息队列的时间(可忽略不计)。

引入消息队列后,用户响应时间是串行模式的3倍,是并行模式的2倍

应用解耦

场景:双11购物节,用户下单后,订单系统告知库存系统

传统做法:订单系统调用库存系统的接口,但是此方法有缺点:一旦库存系统出现故障,订单就会失败;订单系统和库存系统高耦合

引入消息队列:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户下单成功;库存系统监听消息队列,收到消息之后,进行库存相关操作。就算库存系统出现故障,消息队列也会能保证消息的可靠推送,不会导致消息丢失。

流量削峰:秒杀活动中应用广泛

场景:秒杀活动,一般流量较大,导致应用过大,解决此问题可引入消息队列

作用:控制活动人数,超过一定阈值的订单直接丢弃;缓解短时间的高流量压垮应用。

流程:用户发起请求后,将消息写入消息队列,如果消息队列长度超过最大值,则直接抛弃用户请求或跳转到错误界面。秒杀业务系统监听消息队列中的数据,根据其做后续处理

rabbitmq概述

MQ(Message Queue):是一种分布式应用程序的通信方法,是消费者-生产者模型的典型代表,

生产者(producer)往消息队列中不断写入消息,consumer则读取或订阅队列的消息,这点和队列类似,具有FIFO(先入先出)的特点

消息队列:在消息队列模型中,可划分为3个角色,Producer、Queue、Consumer

Producer:生产者,往消息队列中添加数据的角色

Queue:队列,为承载消息的容器。不是栈是因为想使消息先进先出,有序。栈是先进后出

Consumer:消费者,从消息队列中获取数据的角色

理解消息队列:

例如用户下单购买商品,商家将商品订单发给快递公司,快递公司根据商品中买家的信息分发对应的买家

在上述过程中,商品作为消息,商家作为消息的生产者,快读公司作为队列,买家作为消费者。

快递公司根据包裹中买家的地址和电话锁定买家。因此消息队列中队列和消费者也需要一个映射规则,实现Message和Consumer之间的路由

RabbitMQ基本概念

Mseeage:消息,包含消息头(附属配置信息)和消息体(消息实体内容),消息体是不透明的,

消息体是由一些可选属性组成,包括路由键(routing-key)、优先级(priority)、持久化存储(delivery-mode)等

Publisher:消息生产者,向交换机发布信息的程序

Exchange:交换机,接收生产者发送的消息并将这些消息路由给服务器中的消息队列

常见3种交换器:direct、fanout、topic

direct:发布与订阅,完全匹配

fanout:广播,所有订阅该广播的队列都可以收到该消息

topic:主题,规则匹配

Queue:消息队列,保存消息直到发送给消费者。消息容器,也是消息的终点,一个消息可投入一个或多个消息队列,消息一直在队列中,直到消费者将消息取走。

Binding:绑定,用于给Exchange和Queue建立关系,把交换机和消息队列通过路由规则绑定起来,可以是多对多关系

Connection:网络连接

Channel:信道,消息队列和外部联系都是通过信道。消息通过Channel塞进队列或流出队列。客户端每个连接中,可有多个Channel。

因为系统中建立和销毁TCP连接都是非常昂贵的开销,因此引入信道,来复用一条TCP连接。

Consumer:消费者,从消息队列中获取消息的客户端程序

Virtual Host:虚拟主机,表示一批交换器、消息队列和相关对象。一个broker中可以有多个host,用作不同用户的权限分离

Broker:消息队列服务器实体,维护一条生产者到消费者的路线,保证数据从按照指定方式传输。

通信过程:

生产者(Producer)生产消息,消息通过Channel(信息)发送给Broker(服务器主体),Broker再分配给一个Exchange(交换机)

Exchange收到消息后,根据消息中的routingkey(路由键),将消息转发给匹配的QUEUE(消息队列)

QUEUE收到消息后,将消息通过Channel(信道)发送给消费者(Consumer)

Consumer收到消息后,发送ACK(确认标志)给消息队列确认收到消息

Queue收到ACK后,删除消息队列中缓存的此条消息

2.rabbitmq运行机制、rabbitmq支持的六种运行模式

rabbitmq运行机制

AMQP中消息的路由:

过程和JMS存在一些差别,AMQP中引入了Exchange和Binging的概念

生产者将消息发布道Exchange上,消息最终达到队列并被消费者接收,Binding决定了交换器的消息应该发送道那个队列。

Exchange类型:

分发消息时,根据类型的不同分发策略有区别,目前共计4中:direct、fanout、topic、headers。headers和direct完全一致,但性能差很多,几乎用不到。

Direct Exchange:消息中的路由键和Binding中的binding key一致(完全匹配),交换器就将消息发到对应的队列中。完全匹配,单播的模式

Fanout Exchange:每个发到Fanout Exchange上的消息都会分发到所有绑定的队列上,不处理路由键,转发消息最快

Topic Exchange:通过模式匹配分配消息的路由键属性,将路由键和某个模式匹配,此时队列需要绑定再一个模式上。

RabbitMQ支持的消息类型

直连模式:生产者-消息队列-消费者

work queue工作模式:也成为Task Queues 任务模型。

当处理消息较多时,可能生产消息速度远大于消费速度,消息队列中消息会越积越多,无法及时处理,此时可使用work模型,让多个消费者绑定道一个队列,共同消费队列中的主体。

队列中的消息一旦消费,就会消失,不会重复消费

生产者-消息队列-多个消费者

Publish/Subscribe 发布/订阅模式 (广播模式)

fanout 扇出,也称广播

广播模式中,消费发送流程是:可有多个消费者;每个消费者有自己的队列;每个队列都要绑定同一个交换机;

生产者发送消息,只能发到交换机,交换机决定发到那个队列,生产者无法决定

交换机将消息发送给绑定的所有队列

队列的消费者都能拿到消息,实现1个消息被多个消费者消费

总结:一个生产者绑定一个交换机,1个交换机绑定多个队列,每个队列都有对应的消费者,有几个消息队列就有几个消费者。

从而实现交换机将消息发给所有消息队列,1个消息被多个消费者接收

Routing 路由模式

Exchange类型为Direct,可实现不同消息被不同的队列消费

在direct 模型下,

消息发送方向exchange发送消息时,必须指定消息的routingkey

exchange和队列的绑定,不是任意绑定,而是指定一个routingkey(路由key),

exchange不再将消息平等地给每一个队列,而是根据消息的routingkey进行判断,只有队列的routingkey和消息的routingkey完全一致,才会将消息给到指定队列

总结:生产者向exchange发送消息指定routingkey,exchange收到消息后,将消息递交给与routingkey完全匹配的队列;每个队列都有各自的消费者;每个消费者消费各自绑定队列的消息

Topics模式

Exchange的类型为topic,可根据消息中的routingkey匹配道不同的队列,区别在于routingkey绑定队列时,可使用通配符进行模糊匹配。

此模式routingkey一般由1个或多个单词组成,单词之间由于"."分隔。例如item.insert

通配符:*(匹配1个词),#(匹配1个或多个词)

RPC模式

客户端远程调用服务方法,使用MQ可以实现RPC的异步调用,基于Direct交换机实现,流程如下:

客户端既是生产者又是消费者,向RPC请求队列发送RPC调用消息,同时监听RPC响应队列

服务端监听RPC请求队列的消息,收到消息后执行服务端的方法,得到方法返回的结果

服务端将RPC方法返回的结果发送至RPC响应队列

客户端监听RPC响应队列,接收到RPC响应结果

3.springboot整合rabbitmq

安装rabbitmq

springboot整合rabbitmq

目的(核心使用方法):使用RabbitTemplate发送和接收消息

实现步骤r

创建项目,引入spring for rabbitmq的依赖;

创建RabbitAutoConfiguration 自动配置类,并配置自动连接工厂ConnectionFactory

创建RabbitProperties配置类,封装RabbitMQ的配置

RabbitTemplate给RabbitMQ发送和接收消息

使用@RabbitListener和@EnableRabbit来监听消息队列

AmqpAdmin是RabbitMQ系统管理功能组件(在代码中创建交换机、消息队列、绑定规则)

4.rabbitmq-六种工作模式、springboot整合rabbitmq

rabbitmq入门程序

发送端程序:创建连接,创建通道,声明队列,发送消息

接收端程序:创建连接,创建通道,声明队列,监听队列,接收消息

work queue工作模式

两个消费端共同消费同一个消息队列中的数据

应用场景:对于任务较重或任务较多情况下,使用工作队列可以提高任务处理速度

实现关键:多个消费者监听同一个队列,1条消息只会被1个消费者接收,rabbitmq采用轮询方式将消息平均发给消费者,消费者处理完某条消息后,才会收到下条消息

Publish/Subscribe 发布订阅模式

每个消费者监听自己的队列;生产者发送消息给broker后,由交换机将消息转发到绑定此交换机的每个队列,每个绑定交换机的队列都可以接收到数据

实现关键:交换机将消息发送给绑定交换机的所有消息队列

Routing 路由模式

每个消费者监听自己的队列,并设置routingkey;生产者发送消息给交换机,交换机根据routingkey发送消息给指定的消息队列,从而实现不同消费者消费不同的消息

实现关键:交换机和队列绑定指定路由键,发送消息时指定路由键,则发给指定的队列。从而实现指定消费者消费发给指定队列的消息

Topic模式

每个消费者监听自己的队列,并设置带有通配符的routingkey;生产者发送消息给beoker,交换机根据routingkey发送消息给指定的消息队列,从而实现不同消费者消费不同的消息

实现关键:交换机给队列绑定指定含通配符的路由键,发送消息时指定路由键,则发给指定的队列,从而实现消费者消费发给指定队列的消息

Header模式

与routingkey区别在于,取消了routingkey,使用header中的key/value匹配队列

示例:根据用户的通知设置去通知用户,设置只接收email的用户只接收email,只接收sms的用户只接收sms。但是性能较低,故使用较少

RPC

客户端远程调用方法,使用MQ可实现RPC的异步调用,基于Direct交换机实现,流程如下:

客户端既是生产者又是消费者,向RPC请求队列发送RPC调用消息,同时监听RPC响应队列

服务端监听RPC请求队列的消息,收到消息后执行服务端的方法,得到方法返回的结果

服务端将RPC方法返回的结果发送至RPC响应队列

客户端监听RPC响应队列,接收到RPC响应结果

springboot整合rabbitmq

创建rabbitmq配置类,类中定义队列常量、交换机常量、路由键常量,声明交换机、声明队列、绑定交换机和队列

启动类添加注解@EnableRabbit开启支持

消息接收方法上使用@RabbitListener(queue={队列名称})监听指定队列

相关推荐
赵渝强老师12 分钟前
【赵渝强老师】基于ZooKeeper实现Hadoop HA
大数据·hadoop·分布式·zookeeper
谢尔登8 小时前
【Node.js】RabbitMQ 不同交换器类型的使用
node.js·rabbitmq·ruby
问道飞鱼11 小时前
分布式中间件-redis相关概念介绍
redis·分布式·中间件
Gauss松鼠会14 小时前
GaussDB关键技术原理:高弹性(四)
java·大数据·网络·数据库·分布式·gaussdb
latesummer_16 小时前
Kafka下载与安装教程(国产化生产环境无联网服务器部署实操)
分布式·kafka
ok你也是个coder17 小时前
RabbitMQ 基础入门
rabbitmq·rabbitmq基础入门
会有黎明吗18 小时前
完整版订单超时自动取消功能
java·vue·rabbitmq
小扳18 小时前
Redis 篇-初步了解 Redis 持久化、Redis 主从集群、Redis 哨兵集群、Redis 分片集群
java·spring boot·redis·分布式·缓存
兮动人19 小时前
错误: 找不到或无法加载主类 org.apache.zookeeper.server.quorum.QuorumPeerMain
分布式·zookeeper·apache
星辰@Sea20 小时前
ZooKeeper远程连接超时排查与解决
linux·分布式·zookeeper