大型分布式系统具有复杂性、隐匿性、配合性和易变性四大难题,不会存在任何单一软件工程上的突破,能让开发生产力得到一个数量级上的提升。
1、单体架构应用的困境
一个典型的单体架构应用就是将一个应用中所有的功能都打包在一个WAR文件中,并部署在应用服务器(Tomcat)中运行。
单体架构应用结构图
单体架构应用会逐渐变得不稳定,一方面是系统不管增长的复杂性造成的,另一方面是由于系统本身牵一发而动全身的特性造成的,可能一不注意,不常用的模块因为存在内存泄露而造成整个服务无法正常提供服务,甚至引起服务崩溃。
在数据管理上单体架构应用容易产生漏洞,最常见的就是数据管理,在数据层通过写SQL语句操纵数据库表。这种做法相当于埋下不定时炸弹。当数据相关团队修改了数据库结构,由于之前的团队之间使用SQL语句进行处理,在系统编译、打包和测试时都有可能通过,但当在真实的生产环境使用时就有可能造成服务的崩溃(我自己本身已经经历过很多次)。
单体架构的应用在开发时要求我们必须使用同一个技术栈,使得单体架构的应用很难接受或切换到其他框架、语言。
单体架构应用开发对于开发者来说,需要了解更多的东西,如系统架构、统一的开发模式、与之交互的相关模块等,造成了一个新加入的开发者需要更长的时间才能够进行开发状态。
代码库方面也有同样的问题,当多名开发者同时修改的时候,一方面需要开发者自己快速提交所修改的代码,另一方面开发者在每次提交修改时都要心惊胆战地祈求代码不要发生冲突(当然就算是在微服务架构中也是不可避免的,只不过会降低发生冲突的几率)。
2、微服务架构
微服务架构中的服务与之前模块化开发很相似,但服务是有明确服务边界的,更易于开发和管控,同时也更易于单独部署和扩展。
对于一个应用系统包括两部分的需求:第一部分是功能性需求,用于定义一个应用是用来做什么的,该应用系统用来达到什么目的;第二部分就是非功能性需求,包括了对应用系统的扩展性、灵活性、还有性能、运维、安全、测试、监控等需求,这种非功能性需求时用来保障业务系统能够正确、顺畅地运行。而对于微服务架构来说,则着重于后一种需求。
微服务架构的优点:
- 松耦合:各个服务之间只要接口及通信协议不变的情况下,互不影响。
- 抽象:对数据结构和数据源有绝对的控制权,其他服务只能通过该服务才能访问数据。
- 独立:每个微服务可以不影响其他服务的情况下进行编译、打包和部署。
- 应对用户需求的多样性
- 更高可用性和弹性:一个去中心化的应用,每个微服务都可以随时上线或下线
微服务架构的缺点:
- 可用性降低:微服务之间通过远程调用方式,无论是收到网络还是其他的影响造成的不稳定,会大大降低应用的可用性。
- 处理分布式事务较棘手:当一个用户请求涉及多个微服务时,如何保证数据的一致性。
- 全能对象阻止业务拆分
- 学习难度曲线加大
- 组织架构变更:需要制定微服务之间的部署编排、关联关系、回滚计划
3、微服务架构设计
微服务架构设计分为三个步骤:
- 把应用中关键的需求定义出来;
- 识别出采用微服务架构时应用中所包含的所有服务
- 将第一步所定义的关键需求作为架构需求的场景来描述服务之间如何进行写作。
- 切记:不可以一开始从技术的角度去拆分,否则由于业务之间的关联关系很有可能将设计出来的微服务拉入焦油坑中。
微服务粒度
对于微服务来说,最好的方式是先专注于各个服务之间的交互,先把它们划分成粗颗粒度的服务,然后随着系统的升级和功能的提升,再将粗颗粒度的服务逐渐细化,形成更合理的微服务粒度。
微服务拆分原则
- 单一职责原则(SRP):将微服务保持足够小,仅拥有一个业务职责,保持微服务的业务单一性,从而提升应用的稳定性。
- 共同封闭原则(CCP):在业务上联系紧密,同一个原因而改变的服务组织在一个微服务中,一方面可以减少微服务的数量,另一方面当业务发生改变时只需要一个业务开发团队进行单独修改,重新部署即可。减少不同微服务开发团队之间的沟通成本。
微服务自治原则
在微服务治理中有一个重要的理念就是自治,自治范围并不只是代码和数据,还包含微服务的运行和维护管理,所以亚马逊的微服务有一个规则:你构建,你运行。
微服务架构中的数据自治是指每个微服务拥有其业务领域下对象的数据,只有该微服务可以对这些数据进行操作(包含读取与修改),而其他微服务只能通过该服务才能访问到这些数据,不能直接通过数据库进行沟通。
微服务交互原则
- 使用REST协议:强烈建议使用HTTP作为服务的调用协议,并在服务处理上使用HTTP标准动词(GET、PUT、POST和DELETE);
- 使用URI表达:URL能够清晰表达出所要解决的问题、提供的方法、相应资源信息及资源之间的关联关系。
- 使用JSON数据格式:轻量级数据格式协议,自带的序列化和反序列化机制
- 使用HTTP标准状态码。
微服务架构迁移
对于代码重构,有一个很重要的指导思想就是不要大规模进行重构,而是一小步一小步来。
与大规模进行重构相反,在进行微服务架构迁移时可以使用Martin Fowler提出绞杀模式。通过这种方式逐步构建微服务应用,并替代、兼容整合就的传统应用,直到微服务承担全部应用功能。
4、不应使用微服务架构的情形
当我们在开发时遇到以下情形时应避免使用微服务架构:
- 构建分布式架构非常吃力时;
- 服务器蔓延时;
- 采用小型应用、快速产品原型时;
- 对数据事务的一致性有一定要求时。
微服务架构的诞生是为了解决可复用,并且需要快速扩展的大型应用的问题。但假如我们所要构建的应用比较小,功能简单,并且用户量也不是很大,或者我们所要构建的是初期产品,打算先开发出一个MVP,在这个基础上快速迭代找到用户真正关心的功能点,那么,采用微服务架构很显然在这个时候不适合,因为构建微服务架构所需要的一些脚手架就够我们的排期日程了。
微服务架构只能满足CAP理论中的两点,可用性和分区容忍性,强一致性没法完全满足,只能满足最终一致性。