消息中间件(MQ)的定义前端
其实并无标准定义。通常认为,消息中间件属于分布式系统中一个子系统,关注于数据的发送和接收,利用高效可靠的异步消息传递机制对分布式系统中的其他各个子系统进行集成。数据库
高效:对于消息的处理处理速度快。设计模式
可靠:通常消息中间件都会有消息持久化机制和其余的机制确保消息不丢失。服务器
异步:指发送完一个请求,不须要等待返回,随时能够再发送下一个请求,既不须要等待。网络
一句话总结,咱们消息中间件不生产消息,只是消息的搬运工。架构
假设一个电商交易的场景,用户下单以后调用库存系统减库存,而后须要调用物流系统进行发货,若是交易、库存、物流是属于一个系统的,那么就是接口调用。可是随着系统的发展,各个模块愈来愈庞大、业务逻辑愈来愈复杂,必然是要作服务化和业务拆分的。这个时候就须要考虑这些系统之间如何交互,通常的处理方式就是 RPC(Remote Procedure Call)(具体实现 dubbo,SpringCloud)。系统继续发展,可能一笔交易后续须要调用几十个接口来执行业务,好比还有风控系统、短信服务等等。这个时候就须要消息中间件登场来解决问题了。并发
因此消息中间件主要解决分布式系统之间消息的传递,同时为分布式系统中其余子系统提供了松耦合的架构,同时还有如下好处:异步
低耦合,不论是程序仍是模块之间,使用消息中间件进行间接通讯。分布式
异步通讯能力,使得子系统之间得以充分执行本身的逻辑而无需等待。性能
缓冲能力,消息中间件像是一个巨大的蓄水池,将高峰期大量的请求存储下来慢慢交给后台进行处理,对于秒杀业务来讲尤其重要。
伸缩性,是指经过不断向集群中加入服务器的手段来缓解不断上升的用户并发访问压力和不断增加的数据存储需求。就像弹簧同样挂东西同样,用户多,伸一点,用户少,浅一点,啊,不对,缩一点。是伸缩,不是深浅。衡量架构是否高伸缩性的主要标准就是是否可用多台服务器构建集群,是否容易向集群中添加新的服务器。加入新的服务器后是否能够提供和原来服务器无差异的服务。集群中可容纳的总的服务器数量是否有限制。
扩展性,主要标准就是在网站增长新的业务产品时,是否能够实现对现有产品透明无影响,不须要任何改动或者不多改动既有业务功能就能够上线新产品。好比用户购买电影票的应用,如今咱们要增长一个功能,用户买了铁血战士的票后,随机抽取用户送异形的限量周边。怎么作到不改动用户购票功能的基础上增长这个功能。熟悉设计模式的同窗,应该很眼熟,这是设计模式中的开闭原则(对扩展开放,对修改关闭)在架构层面的一个原则。
RPC 和消息中间件的场景的差别很大程度上在于就是“依赖性”和“同步性”。
依赖性:
好比短信通知服务并非事交易环节必须的,并不影响下单流程,不是强依赖,因此交易系统不该该依赖短信服务。若是是 RPC 调用,短信通知服务挂了,整个业务就挂了,这个就是依赖性致使的,而消息中间件则没有这个依赖性。
消息中间件出现之后对于交易场景多是调用库存中心等强依赖系统执行业务,以后发布一条消息(这条消息存储于消息中间件中)。像是短信通知服务、数据统计服务等等都是依赖于消息中间件去消费这条消息来完成本身的业务逻辑。
同步性:
RPC 方式是典型的同步方式,让远程调用像本地调用。消息中间件方式属于异步方式。
相同点:都是分布式下面的通讯方式。
场景说明:用户注册后,须要发注册邮件和注册短信。传统的作法有两种 1.串行的方式;2.并行方式。
串行方式:将注册信息写入数据库成功后,发送注册邮件,再发送注册短信。以上三个任务所有完成后,返回给客户端。
(2)并行方式:将注册信息写入数据库成功后,发送注册邮件的同时,发送注册短信。以上三个任务完成后,返回给客户端。与串行的差异是,并行的方式能够提升处理的时间。
假设三个业务节点每一个使用 50 毫秒钟,不考虑网络等其余开销,则串行方式的时间是 150 毫秒,并行的时间多是 100 毫秒。
小结:如以上案例描述,传统的方式系统的性能(并发量,吞吐量,响应时间)会有瓶颈。如何解决这个问题呢?
引入消息队列,将不是必须的业务逻辑,异步处理。
按照以上约定,用户的响应时间至关因而注册信息写入数据库的时间,也就是 50 毫秒。注册邮件,发送短信写入消息队列后,直接返回,所以写入消息队列的速度很快,基本能够忽略,所以用户的响应时间多是 50 毫秒。所以架构改变后,系统的吞吐量提升到每秒 20 QPS。比串行提升了 3 倍,比并行提升了两倍。
场景说明:用户下单后,订单系统须要通知库存系统。传统的作法是,订单系统调用库存系统的接口。
传统模式的缺点:
1) 假如库存系统没法访问,则订单减库存将失败,从而致使订单失败;
2) 订单系统与库存系统耦合;
如何解决以上问题呢?引入应用消息队列后的方案
订单系统:用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户订单下单成功。
库存系统:订阅下单的消息,采用拉/推的方式,获取下单信息,库存系统根据下单信息,进行库存操做。
假如:在下单时库存系统不能正常使用。也不影响正常下单,由于下单后,订单系统写入消息队列就再也不关心其余的后续操做了。实现订单系统与库存系统的应用解耦。
流量削峰也是消息队列中的经常使用场景,通常在秒杀或团抢活动中使用普遍。
应用场景:秒杀活动,通常会由于流量过大,致使流量暴增,应用挂掉。为解决这个问题,通常须要在应用前端加入消息队列:能够控制活动的人数;能够缓解短期内高流量压垮应用。
用户的请求,服务器接收后,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面;秒杀业务根据消息队列中的请求信息,再作后续处理。
日志处理是指将消息队列用在日志处理中,好比 Kafka 的应用,解决大量日志传输的问题。架构简化以下:
日志采集客户端,负责日志数据采集,定时写入 Kafka队列:Kafka 消息队列,负责日志数据的接收,存储和转发;日志处理应用:订阅并消费 kafka队列中的日志数据;
消息通信是指,消息队列通常都内置了高效的通讯机制,所以也能够用在纯的消息通信。好比实现点对点消息队列,或者聊天室等。
点对点通信:客户端 A 和客户端 B 使用同一队列,进行消息通信。
聊天室通信:客户端 A,客户端 B,客户端 N 订阅同一主题,进行消息发布和接收。实现相似聊天室效果。
卡夫卡与法国做家马塞尔·普鲁斯特,爱尔兰做家詹姆斯·乔伊斯并称为西方现代主义文学的先驱和大师。《变形记》是卡夫卡的短篇表明做,是卡夫卡的艺术成就中的一座高峰,被认为是 20 世纪最伟大的小说做品之一。
若是通常的业务系统要引入 MQ,怎么选型:
用户访问量在 ActiveMQ 的可承受范围内,并且确实主要是基于解耦和异步来用的,能够考虑 ActiveMQ,也比较贴近 Java 工程师的使用习惯,可是ActiveMQ 如今中止维护了,同时 ActiveMQ 并发不高,因此业务量必定的状况下能够考虑使用。
RabbitMQ 做为一个纯正血统的消息中间件,有着高级消息协议 AMQP 的完美结合,在消息中间件中地位无可取代,可是 erlang 语言阻止了咱们去深刻研究和掌控,对公司而言,底层技术没法控制,可是确实是开源的,有比较稳定的支持,活跃度也高。
对本身公司技术实力有绝对自信的,能够用 RocketMQ 。
因此中小型公司,技术实力较为通常,技术挑战不是特别高,用 ActiveMQ、RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强,用 RocketMQ是很好的选择
若是是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,几乎是全世界这个领域的事实性规范。
总体上来看,使用文件系统的消息中间件(kafka、rokcetMq)性能是最好的,因此基于文件系统存储的消息中间件是发展趋势。(从存储方式和效率来看 文件系统>KV 存储>关系型数据库)