中间件
什么是中间件
中间件(Middleware)顾名思义是系统软件和用户软件之间连接的软件,以便于软件各部分之间的沟通,特别是应用软件对于系统软件的集中逻辑,是一种独立的系统或者服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源。中间件在客户端服务器的操作系统、网络和数据库之上,管理计算机资源和网络通信。总的作用是为处于自己上层的应用软件提供运行和开发的环境,帮助用户灵活、高效的开发和集成复杂的应用软件
关于中间件,我们可以理解为:是一类能够为一种或者多种应用程序合作互通、资源共享同时还能够为应用程序提供相关的服务的软件。中间件是一类软件统称,而非一种软件;中间件不仅仅实现互连,还要实现应用之间的互操作
分布式系统
什么是分布式系统
一个请求由服务器端的多个(服务或者系统)协同处理完成
分布式为了解决单个服务器容量和性能瓶颈问题而采用的优化手段,将一个业务拆分成不同的业务,分布在不同的机器上执行。服务之间通过远程调用协同工作,对外提供服务
分布式系统需要解决的问题
该领域需要解决的问题极多,在不同的技术层面上,又包括:分布式缓存、分布式数据库、分布式计算、分布式文件系统等
分布式的实现形式
- 水平扩展:当一台机器扛不住流量时,就通过添加机器的方式,将流量分到所有服务器上,所有机器都可以提供相同的服务
- 垂直拆分:前端有多种查询需求是时,一台机器扛不住,可以将不同的业务需求分发到不同的机器上,比如A机器处理余票查询的请求,B机器处理支付的请求
分布式和微服务的区别
微服务是架构设计方式,分布式是系统部署方式时
微服务架构
微服务
简单来说微服务就是很小的服务,小到一个服务只对应一个单一的功能,只做一件事。这个服务可以单独部署运行,服务之间可以通过RPC来相互交互,每个微服务都是由独立的小团队开发,测试,部署,上线,负责它的整个生命周期
微服务架构
在做架构设计的时候,先做逻辑架构,再做物理架构,当你拿到需求后,估算过最大用户量和并发量后,计算单个应用服务器能否满足需求,如果用户量只有几百人的小应用,单体应用就能搞定,即所有应用部署在一个应用服务器里,如果是很大用户量,且某些功能会被频繁访问,或者某些功能计算量很大,建议将应用拆解为多个子系统,各自负责各自功能,这就是微服务架构
分布式
分布式服务顾名思义服务是分散部署在不同的机器上的,一个服务可能负责几个功能,是一种面向SOA架构的,服务之间也是通过rpc来交互或者是webservice来交互的。逻辑架构设计完后就该做物理架构设计,系统应用部署在超过一台服务器或虚拟机上,且各分开部署的部分彼此通过各种通讯协议交互信息,就可算作分布式部署,生产环境下的微服务肯定是分布式部署的,分布式部署的应用不一定是微服务架构的,比如集群部署,它是把相同应用复制到不同服务器上,但是逻辑功能上还是单体应用
对比
微服务相比分布式服务来说,它的粒度更小,服务之间耦合度更低,由于每个微服务都由独立的小团队负责,因此它敏捷性更高,分布式服务最后都会向微服务架构演化,这是一种趋势,不过服务微服务化后带来的挑战也是显而易见的,例如服务粒度小,数量大,后期运维将会很难
消息中间件
- 利用可靠的消息传递机制进行系统和系统直接的通讯
- 通过提供消息传递和消息的排队机制,他可以在分布式系统环境下扩展进程间的通讯
应用场景
- 跨系统数据传递
- 高并发流量削峰
- 数据的分发和异步处理
- 大数据分析与传递
- 分布式事务
为什么使用MQ?
- 异步处理:相比于传统的串行、并行方式,提高吞吐量
- 应用解耦:系统间通过消息通信,不用关心其他系统的处理
- 流量削峰:可以通过消息队列长度控制请求量;可以缓解短时间内高并发请求
- 日志处理:处理大量日志传输
- 消息通讯:消息队列一般都内置了高效的通信机制,因此也可以用在纯的消息通讯。比如实现对点消息队列,或者聊天室
消息队列的优缺点
优点
解耦
允许独立扩展或者修改两边的处理过程,只要确保他们遵守同样的接口约束
一个系统或者一个模块,调用了多个系统或者模块,互相之间的调用很复杂,维护起来很麻烦,但是其实这个调用是不需要直接同步调用接口的,如果用MQ给它异步化解耦
A系统发送数据到BCD三个系统,通过接口调用发送。如果E系统也需要这个数据呢?那如果 C 系统现在不需要了呢?A系统根其他各种乱七八糟的系统严重耦合,A系统产生一条比较关键的数据,很多系统都需要A系统将这个数据发送过来
如果使用MQ,A系统产生一条数据,发送到MQ里面去;如果某个系统不需要这条数据了,就取消对MQ消息的消费即可。这样下来,A系统压根儿不需要去考虑要跟谁发送数据,不需要维护这个代码是,也不需要考虑人家是否调用成功、失败超时等情况
异步
不需要立即处理消息,消息队列提供了异步处理机制,允许用户把一个消息放入队列中,但不立即处理它,在需要的时候进行处理
A系统接收一个请求,需要在自己本地写库,还需要在BCD三个系统写库,自己本地写库要3ms,BCD三个系统分别写库要 300ms、450ms、200ms。最终请求总延时是 3 + 300 + 450 + 200 = 953ms,接近 1s。
如果使用MQ,那么 A 系统连续发送 3 条消息到 MQ 队列中,假如耗时 5ms,A 系统从接受一个请求到返回响应给用户,总时长是 3 + 5 = 8ms。
削峰
减少高峰时期对服务器压力
使用消息队列能够使关键组件顶住突发(突发流量并不常)的访问压力,而不会为突发的超负荷请求而完全崩溃
可恢复性
系统的一部分组件失效时,不会影响到整个系统。消息队列较低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列的消息任然可以在系统恢复后被处理
缺点
- 系统可用性降低:如果消息队列挂了,系统就无法正常运行
- 系统复杂性提高:加入消息队列,要考虑更多的问题,比如:一致性问题、如何保证消息不被重复消费、如何把正确的消息的可靠传输等。因此考虑的东西增加,复杂性增加
- 一致性问题(分布式事务):A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,这数据就不一致了
消息队列选择
ActiveMQ
老牌的消息中间件,国内很多公司过去运用的非常广泛,功能强大,但是问题在于没法确认ActiveMQ可以支撑互联网公司的高并发、高负载以及高吞吐的复杂场景,在国内互联网公司落地较少。而且使用较多的是一些传统企业,用ActiveMQ做异步调用和系统解耦
RabbitMQ
好处在于可以支撑高并发、高吞吐、性能很高,同时有非常完善便捷的后台管理界面可以使用,支撑集群化、高可用部署架构、消息高可靠支持,功能较为完善。使用较为多
除此之外,RabbitMQ的开源社区很活跃,较高频率的迭代版本,来修复发现的bug以及进行各种优化
但是RabbitMQ也有一点缺陷,就是他自身是基于erlang语言开发的,所以导致较为难以分析里面的源码,也较难进行深层次的源码定制和改造,毕竟需要较为扎实的erlang语言功底才可以
RocketMQ
RocketMQ是阿里开源的,经过阿里的生产环境的超高并发、高吞吐的考验,性能卓越,同时还支持分布式事务等特殊场景
而且RocketMQ是基于Java语言开发的,适合深入阅读源码,有需要可以站在源码层面解决线上生产问题,包括源码的二次开发和改造。
Kafka
Kafka提供的消息中间件的功能明显较少一些,相对上述几款MQ中间件要少很多,但是Kafka的优势在于专为超高吞吐量的实时日志采集、实时数据同步、实时数据计算等场景来设计
因此Kafka在大数据领域中配合实时计算技术(比如Spark Streaming、Storm、Flink)使用的较多。但是在传统的MQ中间件使用场景中较少采用
| ActiveMQ | RabbitMQ | RocketMQ | Kafka | ZeroMQ |
---|
单击吞吐量 | 比RabbitMQ低 | 2.6w/s(消息做持久化) | 11.6w/s | 17.3w/s | 29w/s | 开发语言 | java | Erlang | Java | Scala/Java | C | 主要维护者 | Apache | Mozilla/Spring | Alibaba | Apache | iMatix,创始人已去世 | 成熟度 | 成熟 | 成熟 | 开源版本不够成熟 | 比较成熟 | 只有C、PHP等版本成熟 | 订阅形式 | 点对点(p2p)、广播(发布-订阅) | 提供了4种:direct, topic ,Headers和fanout。fanout就是广播模式 | 基于topic/messageTag以及按照消息类型、属性进行正则匹配的发布订阅模式 | 基于topic以及按照topic进行正则匹配的发布订阅模式 | 点对点(p2p) | 持久化 | 支持少量堆积 | 支持少量堆积 | 支持大量堆积 | 支持大量堆积 | 不支持 | 顺序消息 | 不支持 | 不支持 | 支持 | 支持 | 不支持 | 性能稳定性 | 好 | 好 | 一般 | 较差 | 很好 | 集群方式 | 支持简单集群模式,比如‘主-备’,对高级集群模式支持不好 | 支持简单集群,'复制’模式,对高级集群模式支持不好。 | 常用 多对’Master-Slave’ 模式,开源版本需手动切换Slave变成Master | 天然的‘Leader-Slave’无状态集群,每台服务器既是Master也是Slave | 不支持 | 管理界面 | 一般 | 较好 | 一般 | 无 | 无 |
消息中间件的核心组成部分
- 消息的协议
- 消息的持久化机制
- 消息的分发策略
- 消息的高可用,高可靠
- 消息的容错机制
|