RabbitMq
Posted 赵jc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RabbitMq相关的知识,希望对你有一定的参考价值。
Rabbitmq
一为什么使用MQ?
使用MQ的场景很多,主要有三个:解耦、异步、削峰
- 解耦:A服务可以将消息放在MQ当中,其他的服务可以直接从MQ当中获取消息并进行处理即可,A服务和B服务没有实际的关联,提高了系统的灵活性和扩展性
- 异步:可以将一些非核心的流程,如日志,短信,右键等通过MQ的方式去异步处理,这样做的好处是缩短主流程的响应时间,提升用户的体验
- 削峰:MQ的本质就是业务排队,所以面对突然到来的高并发,现在MQ中排好队一个一个来。削峰的好处就是避免高并发压垮系统的关键组件(如某个核心的服务或者数据库等)
解耦场景
:A系统发送数据到BCD三个系统,通过接口调用发送,如果E系统也要用这个数据呢?那如果C系统现在不需要用这个数据了呢?A系统负责人几乎崩溃…
如果使用MQ,A系统产生一条数据,发送到MQ里面去,如果那个系统需要数据自己去MQ里面取数据,A系统压根不需要考虑消息发给谁,不需要维护这个代码,也不需要考虑人家是调用成功,失败超时等情况
通过一个MQ,Pub/Sub发布订阅消息 这么一个模型,A系统就跟其他系统彻底解耦了
异步场景
:A系统接受了一个请求,需要在自己本地写如数据库,还要在BCD三个系统写入数据库,自己本地需要3ms,BCD三个系统分别需要300ms,450ms,200ms,最终请求的总时延时953ms接近1s,用户体验极差,一般互谅网的企业,对于用户的直接操作,一般要求是每个请求必须在200ms以内完成,对用户几乎是无感知的
如果使用MQ,那么A系统连续发送3条消息到MQ队列当中,假如耗时5ms,A系统从接受一个请求到返回最终响应给用户总是尝试8ms,大大减少了响应时间
削峰场景
:每天0:00到12:00,A系统风平浪静,每秒并发请求数量就50个,结果每次一道12:00-13:00美妙的并发请求就会突然暴增到5000个,但A服务最大的处理能力是2000个,所以当大量请求时服务器会垮掉
使用MQ,将5000个请求写入MQ,A系统慢慢从MQ中拉取请求,在自己的能力范围内处理请求就可以了,这样下来哪怕是高峰期,系统也可以正常使用,但是会有大量的请求积压在MQ当中(可能有上百个),但是短暂的高峰期挤压是ok的,因为高峰期过了之后,A系统就会很快地将积压的消息处理掉(高峰期过后,MQ每秒进入50个请求,但是A系统仍然会以2000个请求的速度去处理)
消息队列的缺点
- 系统可用性降低:系统引入的外部依赖越多,越容易挂掉
- 系统复杂性提高:加入了消息队列之后,要考虑很多方面的问题,比如:一致性问题、如何保证这个消息不被重复消费、如何保证消息的可靠性传输等
- 一致性问题:如果A系统处理完了直接返回,人们都以为处理好了,但要是BCD三个系统里BC写入数库成功了,但是C写入数据库失败了,这是数据就不一致了
中间件
什么是中间件
中间件(Middleware)是处于操作系统和应用程序之间的软件,也有人认为它应该属于操作系统中的一部分。人们在使用中间件时,往往是一组中间件集成在一起,构成一个平台(包括开发平台和运行平台),但在这组中间件中必须要有一个通信中间件,即中间件+平台+通信,这个定义也限定了只有用于分布式系统中才能称为中间件,同时还可以把它与支撑软件和使用软件区分开来。
为什么需要使用消息中间件
具体地说,中间件屏蔽了底层操作系统的复杂性,使程序开发人员面对一个简单而统一的开发环境,减少程序设计的复杂性,将注意力集中在自己的业务上,不必再为程序在不同系统软件上的移植而重复工作,从而大大减少了技术上的负担,中间件带给应用系统的,不只是开发的简便、开发周期的缩短,也减少了系统的维护、运行和管理的工作量,还减少了计算机总体费用的投入。
中间件的特点
为解决分布异构问题,人们提出了中间件(middleware)的概念。中间件位于平台(硬件和操作系统)和应用之间的通用服务,如下图所示,这些服务具有标准的程序接口和协议。针对不同的操作系统和硬件平台,它们可以有符合接口的协议规范的多种实现。
也很难给中间件一个严格的定义,但中间件应具有如下的一些特点:
- (1)满足大量应用的需要
- (2)运行于多种硬件和 OS平台
- (3)支持分布计算,提供跨网络、硬件和 OS平台的透明性的应用或服务的交互
- (4)支持标准的协议
- (5)支持标准的接口
消息中间件的本质及设计
它是一种接受数据、接受请求、存储数据、发送数据等功能的技术服务
MQ消息队列:负责数据的传接受,存储和传递,所以性能要高于普通服务和技术
消息中间件的核心组成部分
- 消息的协议
- 消息的持久化机制
- 消息的分发策略
- 消息的高可用,高可靠
- 消息的容错机制
RabbitMQ
RabbitMQ是什么
简而言之RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件,简而言之就是消息中间件
RabbitMQ服务器使用Erlang语言编写的
RabbitMQ的特点
- 可靠性:RabbitMQ使用一些机制来保证可靠性,例如持久化、传输确认及发布确认等
- 灵活的路由:在消息进入队列之前,通过交换器来路由信息
- 扩展性:多个RabbitMQ节点可以组成一个集群,也可以根据实际业务情况动态的扩展到集群中去
- 支持多种协议:RabbitMQ除了支持原生的AMQP协议还支持STOMP,MQTT等多种消息中间件协议
- 支持多用语言:RabbitMQ支持所有常用的语言
AMQP是什么?
RabbitMQ就是AMQP协议的Erlang实现,是一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。
RabbitMQ如何保证消息的可靠性?
生产者到RabbitMQ:事务机制和COnfirm机制(注意事务机制和Confirm机制是互斥的,不能共存)
RabbitMQ自身:持久化、集群、普通模式、镜像模式
RabbitMQ到消费者:死信机制、消息补偿机制
RabbitMQ如何保证队列的高可用?
RabbitMQ有三种模式:单机模式、普通集群模式、镜像集群模式
- 单机模式:就是demo级别的,一般就在本地启动了玩玩,没人生产使用单机模式
- 普通集群模式:意思就是在多台机器上启动多个RabbitMQ实例,每个机器启动一个
镜像集群模式
:这种模式才是真正RabbitMQ的高可用模式,跟普通集群模式不一样的是,你创建的queue,无论元数据(元数据是指RabbitMQ的配置数据)还是queue里的消息都会存在于多个实例上,然后每次你写消息到queue的时候,都会自动地把消息到多个实例的queue里面进行消息同步
RabbitMQ使用场景
解耦、削峰、异步
- 同步异步的问题(串行)
串行方式:将订单信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务全部完成后,返回给客户端
public void makeOrder()
//1.发送订单
//2.发送短信服务
//3.发送email服务
//4.发送app服务
- 并行方式 异步线程池
并行方式:将订单信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成后,返回给客户端。与串行的差别是,并行的方式可以提高处理的时间
public void test()
//异步
theadpool.submit(new Callable<Object>
//1.发送短信服务
)
//异步
theadpool.submit(new Callable<Object>
//2.
)
//异步
theadpool.submit(new Callable<Object>
//3.
)
//异步
theadpool.submit(new Callable<Object>
//4.
)
存在问题
耦合度高
需要自己写线程池自己维护成本太高
出现了消息可能会丢失,需要你自己做消息补偿
如何保证消息的可靠性你自己写
如果服务器承载不了,你需要自己去写高可用
- 异步消息队列的方式
好处:
- 完全解耦,用 MQ建立桥接
- 有独立的线程池和运行模型
- 出现了消息可能会丢失,MQ有持久化功能
- 如何保证消息的可靠性,死信队列和消息转移等
- 如果服务器承载不了,你需要自己去写高可用,HA镜像模型高可用
高内聚,低耦合
好处:
- 完全解耦,用 MQ建立桥接
- 有独立的线程池和运行模型
- 出现了消息可能会丢失,MQ有持久化功能
- 如何保证消息的可靠性,死信队列和消息转移等
- 如果服务器承载不了,你需要自己去写高可用,HA镜像模型高可用
rabbitmq的几种工作模式
- 简单模式
- Work queues 工作队列模式
特点:一个生产者,多个消费者,每个消费者获取到的消息唯一。
- 发布与订阅模式
一个生产者发送的消息会被多个消费者获取。
生产者:可以将消息发送到队列或者是交换机。
消费者:只能从队列中获取消息。
如果消息发送到没有队列绑定的交换机上,那么消息将丢失。
- 路由模式(绑定交换机)
1、 发送消息到交换机并且要指定路由key
2、 消费者将队列绑定到交换机时需要指定路由key
- 主体模式 topic(支持*#)
将路由键和某模式进行匹配,此时队列需要绑定在一个模式上,“#”匹配一个词或多个词,“*”只匹配一个词。
以上是关于RabbitMq的主要内容,如果未能解决你的问题,请参考以下文章