概述
微服务micro service是和单体应用是对应的一个概念。我们不妨先来回顾单体应用程序是怎样的一种。在微服务提出之前,世界上流行的应用程序大多都是单体应用程序。何为单体应用程序,个人认为其实这更多的是从服务端应用程序架构角度的一个概念。
单体应用程序意味着所有的代码都是在一个项目当中的,这些代码是统一打包部署发布出去的,在一个进程当中跑。
微服务,可以理解为将原来单体应用中的不同模块划分成不同的相对更小的应用程序。
本质上就是一种分而治之的思想。从思想层面来说并没有任何全新的东西。当应用程序越来越复杂,可以说这是一条必经之路。即便是单体应用程序,在整个应用程序内部,不同的功能模块,也是放在不同的包当中的,相关的逻辑也是组织在一起的。
只是微服务将这些模块几乎完全的隔离开了,那么不仅这些代码分开了,他们的打包,部署,运维,甚至数据库都是隔离的。这些微服务之间的交互就通过彼此暴露的api进行。
微服务的优劣
- 微服务的优劣和它自身的特点紧密相连。由于微服务将较大的项目切分成了多块。那么优点是:
- 从需求角度来说:每个微服务都很小,这样能聚焦一个指定的业务功能或业务需求
- 从团队管理的角度来说:微服务能够被小团队单独开发。因此团队更好管理,可以采用敏捷开发的模式。
- 从部署和开发角度来说:微服务是松耦合的,无论是在开发阶段或部署阶段都是独立的。单个服务代码量不会很多,开发启动起来就会很快。
- 从技术选择角度来说:微服务允许选用技术十分灵活,整个项目无需强制要求使用一样的技术栈。
- 从测试角度来说:由于代码相对较少,因此微服务可以进行较快的单元测试和api测试,这样利于实现CI持续集成和CD持续交付。
缺点则有:
- 维要求比较高:单体应用就一个war包,微服务在一个系统中会有很多的服务,每个服务都对应一个包,维护起来就会复杂一些。
- 技术复杂性提高:微服务就会带来一系列的问题,事务问题,Session一致性问题,锁问题,分布式复杂性等。同时虽然单个微服务的测试更加方便,但是应用程序整体的测试以及应用程序相互之间依赖的测试就更加难。contract约定测试在这方面可以提供帮助
怎么解决微服务的问题?
对于devops的问题:
这要求相关人员必须具备devops的能力。所谓devops,就是打包,部署,运行,监控我们的微服务等工作。为什么微服务需要强调这些问题,因为相对于单体应用只需要打包部署单个包而言,对于每个拆分后的微服务进行编译、打包、部署必将是原来工作量的数倍,如果不采用自动化工具,这些工作将会消耗大量的时间和精力也做不好,从这个角度来说,使用自动化工具是必须的。
并且由于多个微服务采用框架各异,那么微服务部署所依赖的基础环境,必将异常复杂繁琐。
可以说DevOps是微服务实施的充分必要条件
对于事务一致性问题,首先必须提出的一点是:你的需求里到底需不需要事务一致性?如果没有,这个问题就不需要考虑。如果有,这个问题才存在。
微服务中的事务一致性问题可能会面临下面这些调整:
首先,对于微服务架构来说,数据访问更加复杂,数据库是微服务私有的,唯一可访问的方式就是通过该微服务的API。这种数据访问方式的好处是使得微服务之间松耦合,并且彼此之间独立非常容易进行性能扩展。
其次,不同的微服务经常使用不同的数据库。应用会产生各种不同类型的数据,关系型数据库并不一定是最佳选择。例如,某个产生和查询字符串的应用采用Elasticsearch的字符搜索引擎;某个产生社交图片数据的应用可以采用图数据库,例如,Neo4j;基于微服务的应用一般都使用SQL和NoSQL结合的模式。但是这些非关系型数据大多数并不支持事务。可见在微服务架构中已经不能选择分布式事务了。
依据CAP理论,必须在可用性(availability)和一致性(consistency)之间做出选择。如果选择提供一致性需要付出在满足一致性之前阻塞其他并发访问的代价。这可能持续一个不确定的时间,尤其是在系统已经表现出高延迟时或者网络故障导致失去连接时。
依据目前的成功经验,可用性一般是更好的选择,但是在服务和数据库之间维护数据一致性是非常根本的需求,因此微服务架构中应选择满足最终一致性。
目前使用比较多的方案是
结合MQ消息中间件实现的可靠消息最终一致性。可靠消息最终一致性,需要业务系统结合MQ消息中间件实现,在实现过程中需要保证消息的成功发送及成功消费。即需要通过业务系统控制MQ的消息状态。
关于微服务的事务问题,更详细的内容暂时可以参考这篇博客:微服务架构下的事务一致性保证
总结
总的来说,对于任何一种技术而言都不是绝对盲目推崇的,适合的才最好,微服务自然有很多好处,但是在实际的项目中依然需要结合实际需求和情况进行实践。但是总的来说,软件项目的趋势是在朝这个方向前进的。越来越多的公司和项目都在采用这种架构模式了。