许多大公司如阿里巴巴,腾讯,微博,滴滴等,已经采用现在所谓的微服务架构模式解决了我们前文所提到的单体应用遇到的种种问题。主要的思路:将应用程序分解成一套较小的互连服务。
# 一、微服务解决方案
一个服务通常实现了一组不同的特性或功能,例如订单管理、客户管理等。每一个微服务都是一个小型迷你应用,在需要依赖的地方,通过REST API连接其他所需要的服务之星业务逻辑。
微服务架构
一些微服务会向外暴露一组供其他模块访问和使用的API。其他微服务实现了自己的业务逻辑,在必要时,可以通过API进行业务逻辑访问。比如,之前提到的单体应用,通过拆解后,可以变成如下的架构:
具体的表现为:应用程序的每个功能区域现在都由自己的微服务实现。例如,以我们的出租车系统为例,一个是乘客的应用,一个是司机的应用。这使得它更容易地为特定的用户、司机、设备或者专门的用例部署不同的场景。每个后端服务暴露一个REST API,大部分服务消费的API由其他服务提供。例如,Driver Management 使用了 Notification 服务器来通知可用司机一个可选路程。UI服务调用了其他服务来渲染页面。
微服务与数据库的关系
既然我们将微服务架构模式明显影响到了应用程序与数据库之间的关系,与其他共享单个数据库模式服务有所不同,其每一个服务都有自己的数据库模式。一方面,这种做法与企业级数据库数据模型的想法相背,此外,它经常导致部分数据冗余。对于微服务架构而言,每一个服务都应该有自己的数据库模式,因为它能实现松耦合。如下图所示:
这种模式下设计架构的特点是每个服务都拥有各自的数据库。而且,服务可以使用一种最适合其需求、号称多语言持久架构的数据库。比如,Driver Management要找到与潜在乘客接近的司机,就必须使用支持高效地理查询的数据库。
【补充:伸缩立方】
无论是单体应用还是微服务架构的应用,在实际的生产环境和数据量增加时,都会面临着应用扩展的需要,用以来提高处理能力。在进行系统伸缩性的探索上,有不同的方法。通常,我们常见的提高系统伸缩性能的方法有以下几种:
- 通过负载均衡器后运行的多个拷贝构成,有N份拷贝,则没份负责处理1/N的负载。比如,当我们的系统流量过大时,我们常常会部署到多个Tomcat上,这些Tomcat均挂载在同一台负载均衡器上,这样每一台Tomcat所处理的业务量就降低为原来的一部分。如下图所示:
- 对数据库进行分解。原来是所有的业务和功能都存放在统一的数据库中,比如叫db1。为了提高系统性能,提高处理数据的能力,可以将原本是耦合,依赖在同一个系统中的业务模块拆分为小规模的多个业务模块,也就是我们说的微服务的实现架构,每个微服务都只实现核心功能,比如订单模块拆分为一个微服务,支付模块拆分为一个微服务。在拆分的过程中,因为每个微服务是独立部署的,所以订单模块对应的订单表存在于一个数据库db1中,支付模块所对应的支付表存在于另外一个数据库db2中。这样就完成了由一个数据库到多个数据库的拆分。如下图所示:
- 对数据表进行拆分。数据库中,同一张表格的数据量过大时,我们的查询等业务在操作数据库时会变得效率下降,我们需要通过其他的方式来提高数据库操作的效率。解决这种同一张表数据的数据量过大的问题,通过拆表来解决。比如我们将0-10000000的数据存放在第1个表中,将10000001-20000000数据存放在第2个表中,依次类推。当我们操作数据库时,到对应的数据库中查询就可以了。如下图所示:
# 伸缩立方
伸缩立方是一本技术书籍中提出的概念,这本书的名称为《The Art of Scalability》。
经过上述我们给大家介绍的系统伸缩性解决方案,进而解释一下伸缩立方。在上述伸缩立方的表当中,分为X轴,Y轴,Z轴。具体轴的方案如下:
- X轴:运行多个负载均衡器后的多个实例。
- Y轴:对应用进一步分解为微服务(分库)
- Z轴:大数据量时,对数据进行分区(分表)
# 二、微服务的优缺点
微服务优点
- 解决复杂问题。微服务架构把可能会变得庞大的单体应用程序分解成一套服务。虽然功能数量不变,但是应用程序已经被分解成可管理的块或者服务。每个服务都有一个明确定义边界的方式,如远程过程调用(RPC)驱动或API。微服务架构模式强制一定程度的模块化,实际上,使用单体代码来实现是极其困难的。因此,使用微服务架构模式,个体服务能被更快地开发,并更容易理解与维护。
- 团队分工协作更容易。微服务这种架构使得每个服务都可以由一个团队独立专注开发。开发者可以自由选择任何符合服务API的技术。当然,更多的组织是希望通过技术选型限制来避免完全混乱的状态。然而,这种自由意味着开发人员不再有可能在这种自由的新项目开始时使用过时的技术。当编写一个新服务时,他们可以选择当前的技术。此外,由于微服务体积较小,使用当前技术重写旧服务将变得更加可行。
- 独立部署。微服务架构模式可以实现每个微服务独立部署。开发人员根本不需要去协调部署本地变更到服务。这些变更一经测试即可立即部署。比如,UI团队可以经过自己的开发和测试,并快速迭代UI变更。微服务架构模式使每个聚焦于自己核心业务的团队有了更多的自主权。
- 程序扩展能力强。微服务架构模式使得每个服务能够独立扩展。开发者可以仅部署满足每个服务的容量和可用性约束的实例数目,另外每个开发团队还可以使用与服务资源要求最匹配的硬件。比如,我们可以在云服务器A实例上部署一个图像处理服务,而在云服务器B实例上部署一个内存数据库服务。微服务架构下使得我们分开部署实例变成了现实。
以上几点是,我们描述了微服务的优点。和单体应用相比,微服务有其优点,当然也会有不足。
微服务缺点
- 规模难以界定。如同微服务的名字一样,以微服务架构为主的设计模式重点过于强调拆分和微型,以至于会导致一个大型项目会被拆分出很多的微服务实例。在拆分的过程中,如何定义微服务迷你应用的规模,往往存在着不同的标准,有人是以核心功能为标准,有人主张以代码量为标准。总之,衡量标准不一。我们需要强调的是:微服务仅仅是一种技术手段,而不是主要目标。微服务的目标在于充分分解应用程序以方便应用敏捷开发和部署。
- 增加系统复杂度。因为微服务是独立部署,拆分成各个功能服务实例。因此,原本的单体应用就变成了一个分布式系统,如何管理这个分布式系统,无形之中增加了原有应用程序的复杂度。在分布式系统中,要实现各个微服务实例之间的通信和业务调用,开发者需要选择和实现基于消息或者RPC框架的进程间通信机制来实现微服务间通信。另外,多个微服务调用之间的请求,调试,协调等问题,也会增加团队间的沟通成本,相比起单体应用来说,微服务架构在这一点上也要更复杂。
- 分区数据库架构难题。当我们在进行正常的业务开发时,往往需要涉及到多个模块之间的数据调用和数据更新。在原来的单体应用下,比较容易实现,我们只需要操作不同的实体表就可以实现,但是在微服务架构中,因为数据存储是独立存储和部署,这导致我们在某个业务中更新多个模块数据时,我们需要调用不同的微服务接口API依次更新。在实际的开发和实践过程中,这个问题也会成为开发人员的主要困扰之一。
- 项目测试难度增加。在原来的单体应用中,开发者可以通过在统一的测试目录下统一编写测试用例和测试方法,然后启动应用服务,进行测试系统功能,对开发人员来说这是常见的做法也是比较熟悉的做法。相比较而言,如果我们要进行微服务的功能测试,就需要将所依赖的所有的微服务都要启动起来才能执行。虽然这个工作难度不大,但是要知道,一旦我们的某个微服务实例依赖的其他实例数量较多时,对开发者调试的工作量来说,是直线上升的。
- 多服务修改更加困难。比如在原本的单体应用中存在三个模块,分别为:模块A、模块B和模块C。当我们有业务逻辑需要进行修改时,我们只需要在同一个应用程序中协作修改三个模块,完成业务功能的调整,然后测试并上线。但是在微服务中,当我们需要横框多个微服务实例间进行业务调整时,就需要仔细认真规划和协调,以便完成整个业务的调整。这样对开发者来说,迭代维护的成本也会增加。
- 微服务需要进行多次部署。原来的单体应用在部署时,可以通过将所有的项目模块打包到一个整体的部署包内,然后部署到一台或者一组服务器上。相比较之下,将程序改为微服务架构以后,应用程序的数量就变多了,这样在整体运行时就需要部署多次,这是一个不小的工作量。
以上几点是微服务架构不足的地方。我们必须要辩证的看待和使用微服务,本质上它是一项技术,我们要利用微服务技术解决现实项目中的问题。