我国企业从20世纪80年代开始就逐渐进行信息化建设,由于方法和体系的不成熟,以及企业业务和市场需求的不断变化,—个企业可能同时运行着多个不同的业务系统,这些系统可能基于不同的操作系统、不同的数据库、异构的网络环境。现在的问题是,如何把这些信息系统结合成一个有机地协同工作的整体,真正实现企业跨平台、分布式应用。
中间件便是解决之道,它用自己的复杂换取了企业应用的简单,接下来我们来了解一下什么是中间件?
# 什么是中间件
百度百科:中间件(Middleware)是介于应用系统和系统软件之间的一类软件,它使用系统软件所提供的基础服务(功能),衔接网络上应用系统的各个部分或不同的应用,能够达到资源共享、功能共享的目的。
它并没有很严格的定义,但是普遍接受IDC的定义:中间件是一种独立的系统软件服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源,中间件位于客户机服务器的操作系统之上,管理计算资源和网络通信。从这个意义上可以用一个等式来表示中间件:中间件=平台+通信,这也就限定了只有用于分布式系统中才能叫中间件,同时也把它与支撑软件和实用软件区分开来。
中间件的概念听起来高大上,但其实我们平时都在使用,例如MySQL就可以看作是具备中间件特性的一种技术,中间件技术必须遵循一定的规范和协议,例如 TCP/IP、UDP协议等等,无规矩不成方圆,只有遵守一定的协议才能去处理事情。MySQL 就遵循了 TCP/IP 协议,在我们平常的开发中使用不同的编程语言比如 Java、Go、Python 等来操作 MySQL 的前提也是要遵循 TCP/IP协议,根据此协议实现了不通语言的连接模块来达到通信的目的。由此说使用中间件需要解决的第一个问题就是互通性,也就是相互间可以通信。我们后续学习到其他中间件可能会看到更多其他的协议,比如 AMQP、HTTP 协议等等,为什么呢?因为 TCP/IP 协议是底层的操作系统协议,它并不能满足我们业务场景中的所有需求,所以在其基础上构建一个自己请求信息来实现一个新的协议,比如 AMQP 协议就在信息头中增加消息内容tag标签、队列名、交换机名、连接定制信息等等。
此外,中间件的第二个关键点是平台,平台就是用不同语言开发的应用程序,它们通过遵循某种协议和规范就能和底层操作系统硬件打交道来实现跨平台的效果,这就是中间件。
中间件为了解决这些通信和平台这两大问题采用了很多协议/技术/方法论,如下所述:
- RMI(Remote Method Invocations,远程调用)
- Load Balancing(负载均衡,将访问负荷分散到各个服务器中)
- Transparent Fail-over(透明的故障切换)
- Clustering(集群用多个小的服务器代替大型机)
- Back-end-Integration(后端集成,用现有的、新开发的系统如何去集成遗留的系统)
- Transaction事务(全局/局部)全局事务(分布式事务)局部事务(在同一数据库联接内的事务)
- Dynamic Redeployment(动态重新部署在不停止原系统的情况下,部署新的系统)
- System Management(系统管理)
- Threading(多线程处理)
- Message-oriented Middleware(面向消息的中间件(异步的调用编程)
- Component Life Cycle(组件的生命周期管理)
- Resource pooling(资源池)
- Security(安全)
# 为什么要使用中间件
屏蔽了底层操作系统的复杂性
中间件技术首先能屏蔽底层操作系统的复杂性,我们对数据进行增删改查并不需要与底层操作系统的硬盘等各种指令打交道,我们只需要知道MySQL怎么使用,与MySQL进行交互即可,不需要管它是怎么进行存储和互联互通的。但是中间件的开发者就必须了解各种协议以及底层如何与操作系统的各种硬件进行交互的。
屏蔽技术架构的复杂性
第二,中间件技术可以屏蔽技术架构的复杂性,以前单体架构所有服务都集中在一起用一种语言进行开发,但如今分布式架构下每一个微服务都可以采用不同的语言不同的技术栈,使用中间件就可以将不通的服务来连接互通起来,将不同技术架构的服务串联起来,来达到一个更加稳健、缩短开发周期维护成本低目的。
中间件屏蔽了底层操作系统的复杂性,使程序开发人员面对一个简单而统一的开发环境,减少程序设计的复杂性,将注意力集中在自己的业务上,不必再为程序在不同系统软件上的移至而重复工作,从而大大减少了技术上的负担。中间件带给系统的,不只是开发的便捷,开发周期的缩短,也减少了系统的维护、运行和管理的工作量,还减少了计算机总体费用的投入。
# 中间件特点
为解决分布异构问题,人们提出了中间件的概念。中间件是位于平台(硬件和操作系统)和应用之间的通用服务,如下图所示,这些服务具有标准的程序接口和协议,针对不同的操作系统和硬件平台,他们可以有符合接口和协议规范的多种实现。
如今的开发都采用的分布式架构,就是将一个系统拆分为若干份,比如一个淘宝app可能分为订单系统、用户系统、支付系统等等,订单系统可能采用Java开发、用户系统采用Go开发、支付系统采用Python开发,这些系统之间如何进行互联互通的呢?一个项目从单体架构拆分成微服务架构要解决的第一个问题就是选择什么样的中间件技术来处理不同服务间的通讯问题,中间件为了解决通信的方式有很多种,比如RMI协议,典型的socket通信、dubbo采用的协议都遵循了RMI协议。不仅如此,中间件还需具备高可用的功能,因为每个微服务往往都采用集群的方式部署,比如订单系统将数据通过中间件发送给支付系统,中间件就一定要保证数据的不丢失且高效送达。此外,还需具备持久性,也就是数据可以存盘用于备份。这些都是中间件技术必须解决的问题。
我们常用的 MQ、Redis、Nginx 等中间件都是都具备了中间件的通讯、高可用、高可拓展、持久化等特性,没有具备的话也会通过技术来补充,比如 MySQL 本身不具备高可用性,于是出现了 Mycat、ShardingJDBC 等技术。
综上所述,中间件的特点可以概括为以下几点:
- 满足大量应用的需要
- 运行于多种硬件或OS平台
- 支持分布计算,提供跨网络、硬件和OS平台的透明性的应用或服务的交互
- 支持标准的协议
- 支持标准的接口
由于标准接口对于可移植性和标准协议对于互操作性的重要性,中间件已经成为许多标准化工作的主要部分。对于应用软件开发,中间件远比操作系统和网络服务更为重要,中间件提供的程序接口定义了一个相对稳定的高层应用环境,不管底层的计算机硬件和系统软件怎么更新换代,只要将中间件升级更新,并保持中间件对外的接口定义不变,应用软件几乎不需要修改,从而保护了企业在应用软件开发和维护中的重大投资。
简单说:中间件有个很大的特点,是脱离于具体设计目标,而具备提供普遍独立功能需求的模块。这使得中间件一定是可替换的。如果一个系统设计中,中间件是不可替换的,不是架构、框架设计有问题,那么就是这个中间件,在别处可能是个中间件,在这个系统内是引擎。
# 什么时候使用中间件技术
在项目的架构和重构中,使用任何技术和架构的改变我们都需要谨慎斟酌和思考,因为任何技术的融λ和变化都可能人员、技术和成本的增加,中间件的技术般现在些互联网公司或者项目中使用比较多,如果你仅仅还只是一个初创司建议还是使用单体架构,最多加个缓存中间件即可,不要盲目迫求新或者所谓的高性能,而追求的背后一定是业务的驱动和项目的驱动,因为一旦追求就意味着你的学习成本,公司的人员结构以及服务器成本,维护和运维的成本都会加,所以需要谨忪择和考虑。 但是作为一个开发人员,一定要有学习中间件技术的能力和思维,否则很容易当项目发展到一个阶段在去掌握估计或者在面试中提及,就会给自己带来不小的困扰,在当今这个时代这些技术也并不是什么新鲜的东西,如果去掌握和挖掘最关键的还是自己花时间和花精力去探讨和研究
# 常用中间件技术
这里将常用中间件分为了四类:分布式中间件、负载均衡中间件、缓存中间件、数据库中间件。这些中间件在我们的应用场景中肯定是会涉及到的:
对于分布式中间件,常用的有以下四个:
- ActiveMQ是遵循JMS规范AMQP协议的消息中间件,由Java语言开发,这个中间件比较老牌,目前使用的已经比较少了。如果我们作为一个当下比较新潮技术的开发者的话,使用该中间件的复杂性远比RabbitMQ高,因此ActiveMQ不再作为我们学习的参考。
- RabbitMQ是当下流行的,是国内大厂都在使用的,其中有几个原因,因为它支持分发的模式、持久化、和对容错性等各种机制的处理比较完善,而且和spring框架是同一家公司开发的产品,因此spring框架对其的支持比较完善,因此在java领域十分广泛。
- Kafka是基于tcp/ip这种二进制传输协议进行开发,所以它的性能是最好的,最接近底层,但是它不支持事物、但是支持持久化和分发机制,也是比较完善,在大数据领域用的很多
- RocketMQ是由阿里、滴滴等联合开发出来的一款国产消息队列,对于该产品保持中介态度,建议不要选择使用,因为这属于一种半开源状态,虽然已经脱光诶apache基金会, 但是不太稳定,如果哪一天团队不在维护升级,出现了问题无法解决的话仍要重新选择,因此开发中一定要选择最稳定最可靠的技术,而不是盲目的追求新。
对于负载均衡中间件,常见的有 Nginx
、LVS
、KeepAlive
、CDN
。其中我们着重需要了解的是 Nginx
和 CDN
,因为LVS
和 KeepAlive
在短期的中小型项目中是用不到的。LVS
用于 Nginx
发生故障需要对其做集群架构处理的,KeepAlive
是以保持心跳维持高可用为目的的,CDN
就是用于加速网页加载、渲染速度的。
对于缓存中间件,一定要遵循 tcp/ip 协议,常见的有MemCache
和Redis
。其中 MemCache 是代码级别的,它会将缓存写入代码中,占用 jvm 内存,在一些小项目和非特别领域可以采用。考虑到分布式架构最好使用 Redis。
对于数据库中间件,我们知道 MySQL 本身是具有持久化功能但是不具有高可用性的,也就是没有集群。因此要实现 MySQL 的集群/分库分表的话就必须要使用第三方的中间件例如Mycat
、ShardingJDBCD
等等来协助 MySQL 完成它的高可用性。
以上技术都能很好的帮我们解决项目中的一些场景,比如异步数据的保存可以达到削峰的目的,因为异步可以实现从串行到并行,以及消息分发、分布式事务、消息容错等等场景…