原文章链接:消息队列MQ快速入门(概念、RPC、MQ实质思路、队列介绍、队列对比、应用场景)_zmq rpc-CSDN博客
要理解MQ,就需知RPC通信模型,RPC(全程Remote Procedure Call,远程过程调用),是一个可以像调用本地服务一样调用远程服务的计算机通信协议.
从本质上看,RPC一般对于客户端来说是一种同步的远程服务调用技术,而一般来说MQ是异步的远程调用
实体对象:
服务提供者(provider):提供具体的调用方法的系统,根据上图也就是服务端,服务端才是方法真正的提供者
服务消费者(consumer):调用服务的系统,根据模型图,也就是客户端
序列化(Serialization):将对象转换为便于进行网络传输的二进制或文本数据的过程
反序列化(Deserialization):二进制或文本数据再还原为对象的过程
RPC调用步骤:
1.建立通信:消费者要想调用提供者的方法,首先要和提供者建立通信连接,主要是通过客户端和服务器之间建立TCP连接实现的
2.服务寻址:寻址实现的是确定提供者的IP、端口号以及方法的名称
3.网络传输:消费者发起一个RPC调用时,将调用方法和参数的数据进行序列化传输给提供者,再通过网络传输将二进制数据发送回给消费者
4.服务调用:提供者进行本地调用后得到了返回值,提供者将返回值进行序列化操作后,再通过网络传输将二进制数据发送回给消费者
1.MQ的特点:面向数据、生产者与消费者、有缓冲节点、异步、系统级/模块级通信
2.MQ适用场景:
1、消息的发送者和消费者需要解耦(发送者和消费者都不再直接交互,而是通过中间件间接交互,实现了解耦)
2、发送者并不明确谁是消费者(也是因为发送者和消费者不进行直接交互)
3、发送者并不关心谁来消费信息(理由同上)
4、各个消费者可以从不同的角度入手处理消息
5、消费者的处理结果也不返回给发送者
6、消息的发送和处理是异步的
7、消息的关注者不止一个
3.MQ使用总结,也就是计算结果不要求立即返回给消息的发送者时,应该使用MQ,例如日志服务、业务监控服务
1.RPC特点:面向动作、请求响应模式、同步、对象级/函数级通信
2.RPC适用场景
1、客户端必须明确要调用哪个服务器
2、调用需要立即得到返回结果
3、架构简单
3.RPC使用总结,如果服务的调用需要在短期内返回结果时,并且同一个请求的关注者只有一个,这个时候就应该使用RPC
原始模型的两个关键词:消息和队列
消息:需要传输的数据,可以是最简单的文本字符串,也可以是自定义的复杂格式
队列:一种先进先出的数据结构,在这里是存放消息的容器,入队即发消息的过程,出队即收消息的过程
过程:生产者将消息投递到一个叫做队列的容器中,然后再从容器中取出消息,最后转发给消费者
队列模型(又叫做点对点模型)
点对点模式(PTP):一个生产者发送的每一个消息,都只有一个消费者消费,看起来就像消息从一个点被传递到另一个点,也就是单播
它允许多个生产者向同一个队列里发送消息,但是只有一个消费者能拿到数据,如果有多个消费者,那么多个消费者是竞争者关系,最终一条消息只能被其中一个消费者接收到,读完即会被删除
发布订阅模式(PubSub):一个生产者发送的每一个消息,都会发送到所有订阅了此队列的消费者,也就是广播
在发布订阅模型中,存放消息的容器变成了主题(主题也是一个队列),订阅者在接收消息之前需要先订阅主题,最终,每个订阅者都可以收到同一个主题的全量消息,可以看到和队列模式唯一不同的就是,发布订阅模式中的一份消息数据可以被多次消费
ActiveMQ特性:
Apache出品、最流行的、能力强劲的开源消息总线
完全支持JMS1.1和J2EE1.4规范,【这里是来自菜鸡的吐槽,我又不知道JMS是啥,计算机真是越学越多/(ㄒoㄒ)/~~。查询了一番,才知道JMS(Java Message Service)即java消息服务应用程序接口,是一个Java平台关于面向消息中间件的API,用在两个应用程序之间,或者分布式系统中发送消息,进行异步通信】,总之JMS提供了良好的标准和保证
广泛的连接选项,支持的协议众多有:HTTP、HTTPS、IP多播、SSL、STOMP、TCP、UDP、XMPP等等。促使ActiveMQ拥有很好的灵活性
多种持久化选择,且安全性完全可以依据用户需求进行自定义鉴权和授权
支持的客户端语言种类众多:Java、C++、.NET、Perl、PHP、Python、Ruby
代理集群,多个ActiveMQ代理可以组成一个集群来提供服务,且保证了高性能,客户端-服务端,点对点
管理简单。ActiveMQ是以开发者思维被设计的,有多种方法可以监控ActiveMQ不同层面的数据
对Spring的支持 可以很容易内嵌到使用Spring的系统中去,且支持Spring2.0的特性
支持通过JDBC和journal提供高速的消息持久化
支持Ajax
RabbitMQ特征:
流行的开源消息队列系统,erlang语言开发(也不知道是个啥语言,暂时不去查了,越查越多),这个语言支持你能想到的所有编程语言
按照AMQP(高级消息队列协议)的标准实现,这个协议从根本上避免了生产厂商的封闭,使用任何语言的各种客户都可以从中受益
用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗
灵活的路由:消息在到达队列前是通过交换机进行路由的,RabbitMQ为典型的路由逻辑提供了多种内置交换机类型。如果有更复杂的路由需求,可以将这些交换机组合起来使用,甚至可以实现自己的交换机类型,并且当作RabbitMQ的插件来用
消息集群:在相同局域网中的多个RabbitMQ服务器可以聚合在一起,作为一个独立的逻辑代理来使用
队列高可用:队列可以在集群中的机器上进行镜像,以确保在硬件问题下还保证消息安全
多种协议的支持:支持多种消息队列协议
管理界面:RabbitMQ有一个易用的用户界面,使得用户可以监控和管理消息Broker的许多方面
跟踪机制:如果消息异常,提供了消息跟踪机制,使用者可以找出发生了什么(要不说人主流呢)
插件机制:提供了许多插件
Kafka特征:
分布式消息发布订阅系统,其分区特性、可复制和可容错都是其不错的特性
快速持久化,可在O(1)的系统开销下进行消息持久化
高吞吐,在一台普通的服务器上就可以达到10W/s的吞吐率
完全的分布式系统,Broker、Producer、Consumer都原生自动支持分布式、自动实现负载均衡
支持同步和异步复制两种
支持数据批量发送和拉取
zero-copy:减少IO操作步骤
数据迁移、扩容对用户透明
无需停机即可扩展机器
其他特性:严格的消息顺序、丰富的消息拉取机制、高效订阅者水平扩展、实时的消息订阅、亿级的消息堆积能力、定期删除机制
RocketMQ特征:
具有高性能、高可靠、高实时、分布式特点
Producer、Consumer、队列都可以分布式
Producer向一些队列轮流发送消息,队列集合称为Topic,Consumer如果做广播消费,则一个consumer实例消费这个Topic对应的所有队列,如果做集群消费,则多个Consumer实例平均消费这个topic对应的队列集合
能够保证严格的消息顺序
提供丰富的消息拉取模式
高效的订阅者水平扩展能力
实时的消息订阅机制
亿级消息堆积能力
较少的依赖
可以运行在Java语言所支持的平台之上
ZeroMQ特征:
号称史上最快的消息队列,其他消息队列和它不是一个级别的,但是与此同时带来的是会丢失一些消息
ZMQ实际类似与Socket的一系列接口,和Socket的区别是:普通Socket是端对端的,而ZMQ是N:M的
可用于node与node间的通信,node可以是主机或进程
举例:购物系统中的订单支付:在订单支付成功后,需要更新订单状态、更新用户积分、通知商家有新订单、更新用户标签几个操作。那么在没有MQ之前,我们老老实实的一步接着一步做,像这样
引入MQ之后,整个流程是这样的
引入MQ之后,订单支付只需要关注它的主要流程更新订单状态即可,然后就把消息丢到MQ,其他不核心的东西就由MQ进行通知,这就是MQ解决的最核心的问题应用解耦,也就是只关注最核心的部分
异步通信:MQ的引入,更新用户积分、通知商家、更新用户标签这些步骤不再是串行的了,而是变成了异步执行,这减少了订单支付的整体耗时,提升了订单系统的吞吐量
流量削峰:队列转储了消息,做了一个中间站,对于超出系统承载能力的场景,"MQ"作为漏斗进行限流保护,就是说把最高的峰值削一部分给峰谷,就好像把波浪线修成直线一样,均衡一下
消息的延时消费:队列本身的特征是先进先出,也就是说是有序的,利用队列+定时任务就能实现消息的延时消费
模拟场景:用户注册后,需要发送注册邮件和注册短信
传统做法:
串行:注册信息放入数据库后,先发邮件,再发短信,全部完成后,返回给用户注册成功
并行:注册信息放入数据库后,同时进行发送邮件和发送短信,全部完成之后,返回给用户注册成功
引入MQ之后,注册信息写入数据库后,将消息放入MQ,马上通知用户注册成功,发送注册邮件和短信由MQ去通知
场景:用户下单后,订单系统通知库存系统
传统做法:订单系统调用库存系统的接口,一旦一个系统无法使用,必定会导致另一个系统也无法使用
引入MQ后:订单系统和库存系统不再直接交互
订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户下单成功
库存系统:订阅下单的队列,采用推/拉的方式,获取下单信息,根据下单信息,进行库存操作
假如其中一个系统无法正常使用,只要MQ健在,另一个系统将不受影响
场景: 秒杀或者团抢活动,一般因为流量过大,导致流量暴增,应用挂掉
传统方法: 加服务器
引入MQ后:在应用前端加入消息队列,秒杀时将消息不断丢入队列,等待业务根据规则读取队列中的消息进行处理
场景:大量日志进行传输
引入MQ后: kafka的优秀展示场景
场景:分为点对点通讯(也就是单向私聊)和聊天室(也就是群聊或双向私聊)
点对点通讯: 两个客户端之间公用一个队列
聊天室通讯:多个客户端订阅同一主题(注意这里是订阅不是消费,说明一个消息可以被多次消费)