微服务简介 #
倡导者:Martin Fowler,文章网址:http://martinfowler.com/articles/microservices.html
简而言之,微服务体系结构风格是一种将单个应用程序开发为一组小服务的方法,每个小服务都在自己的进程中运行,并使用轻量级机制(通常是HTTP资源API)进行通信。这些服务是围绕业务功能构建的,可以通过完全自动化的部署机制独立部署。这些服务的集中管理是最低限度的,可以用不同的编程语言编写,并使用不同的数据存储技术。
web系统的架构演变 #
单体应用模式 -> 垂直应用架构模式 -> SOA(面向服务架构模式) -> 微服务架构
1、单体应用模式 #
- 优点:
- 系统开发结构简单,迅速
- 部署,上线简单
- 成本低:一台机器安装:tomcat + mysql + redis + ……
- 缺点:
- 功能的耦合度高,扩展性差
- 不稳定,功能之间可能相互影响,一个地方可能导致整个项目都会崩溃
- 做集群,做分布式非常的不方便
- 可能存在资源浪费
2、垂直应用架构模式 #
-
特点:将上述的单体应用,按照业务功能进行分离,分离一个又一个的相互独立的子系统
-
例如:百度拆分为:搜索,地图,贴吧,新闻,翻译,云盘……
-
优点
- 系统之间的耦合度低,相互之间互不干扰
- 系统分离关注,从开发到测试到上线,甚至到运维集群实现
- 资源可以得到更加合理的分配
-
缺点
- 重复代码过多
3、面向服务架构模式(SOA) #
-
由于上述的垂直应用架构, 重复代码太多,一些架构师就想了一套办法将重复应用和单独应用进行分离,分离之后,抽离出一个层:服务层
-
产品:阿里巴巴的Dubbo框架
-
中小型公司,由于没有架构师,无法抽离服务层,如同扯淡
-
优点:
- 系统的扩展性非常好,系统之间的耦合度相对而言比较低
- 开发到测试到上线,都可以进行分离关注
- 资源可以合理的利用
-
缺点:
- 只有业务非常复杂的系统,并且对SOA非常熟悉的团队才可以使用(大厂的产品)
- 如何抽象服务层是整体架构体系,最为复杂的地方
- 分布式事务控制,服务资源的成本,开发维护的成本都会急剧上升
- 为了中小厂也可以玩一玩分布式,所有微服务的概念就被提出来了
4、微服务架构模式 #
-
在垂直应用架构的基础上,演变而来的一种架构,区别:现在的微服务之间可以相互通讯
-
而且在相互调用时,采用最基本的HTTP通讯协议
-
每个微服务程序都是一个独立的个体,个体中完整的包含了:表现层,业务层,持久层
-
优点:
- 通过业务功能将系统进行拆分,拆分之后耦合度降低,特别满足:“高内聚,低耦合”
- 更加便于程序员采用分离关注的思想,完成对系统的开发,测试,上线
- 整个系统来讲,功能的扩展非常的强,满足:“开闭原则”
-
缺点:
- 上线,部署,维护较为麻烦,运维的工作量将大大提升
- 如果微服务拆分“粒度”不合适,将大大提升系统的复杂度
单体应用服务和微服务的区别 #
| 单体 | 微服务 |
|---|---|
| 所有业务模块都集中在一个应用中 | 根据业务拆分出不同的微服务应用 |
| 修改任何一处代码,都要重新部署整个应用 | 修改某个微服务的代码,只需要重新部署该微服务应用即可 |
| 无法针对于高热业务,单独做集群部署 | 如果某个微服务的并发量特别高,可以针对于该微服务做集群 |
| 开发团队人员特别多,代码冲突也特别多 | 每个微服务都有独立的团队的维护,代码冲突也仅限于当前微服务的团队中 |
微服务的适用场景 #
-
微服务的拆分,拆分“粒度”可大可小,大可以以子系统为单位来进行拆分,小可以以某一个功能块的业务功能来拆分
-
那什么样的系统,适合于进行微服务的拆分?能不能做成微服务,取决于四个要素:
-
- 小:能不能拆,拆分之后微服务的体积是否比较小
- 独:能够独立的开发,测试,部署和运行
- 轻:使用轻量级的HTTP通信机制和架构
- 松:微服务之间是相对而言是比较松耦合的
微服务设计原则 #
- 单一职责原则
- 意思是每个微服务只需要实现自己的业务逻辑就可以了,比如订单微服务,它只需要处理订单的业务逻辑就可以了,其它的不必考虑
- 服务自治原则
- 意思是每个微服务从开发、测试、运维等都是独立的,包括存储的数据库也都是独立的,自己就有一套完整的流程,我们完全可以把它当成一个独立的项目来对待,不必依赖于其它模块
- 轻量级通信原则
- 首先是通信的语言非常的轻量,该通信方式需要是跨语言、跨平台的,之所以要跨平台、跨语言就是为了让每个微服务都有足够的独立性,可以不受技术的钳制
- 接口明确原则
- 由于微服务之间可能存在着调用关系,为了尽量避免以后由于某个微服务的接口变化而导致其它微服务都做调整,在设计之初就要考虑到所有情况,让接口尽量做的更通用,更灵活,从而尽量避免其它模块也做调整
微服务的优势和缺陷 #
优势 #
- 易于开发和维护
- 由于微服务单个模块就相当于一个项目,开发这个模块我们就只需关心这个模块的逻辑即可,代码量和逻辑复杂度都会降低,从而易于开发和维护
- 启动较快
- 这是相对单个微服务来讲的,相比于启动单体架构的整个项目,启动某个模块的服务速度明显是要快很多的
- 局部修改容易部署
- 在开发中发现了一个问题,如果是单体架构的话,我们就需要重新发布并启动整个项目,非常耗时间;但是微服务则不同,哪个模块出现了bug我们只需要解决那个模块的bug就可以了,解决完bug之后,我们只需要重启这个模块的服务即可,部署相对简单,不必重启整个项目从而大大节约时间
- 技术栈不受限
- 比如订单微服务和电影微服务原来都是用java写的,现在我们想把电影微服务改成node.Js技术,这是完全可以的,而且由于所关注的只是电影的逻辑而已,因此技术更换的成本也就会少很多
- 按需伸缩
- 上面说了单体架构在想扩展某个模块的性能时不得不考虑到其它模块的性能会不会受影响,对于我们微服务来讲,完全不是问题,电影模块通过什么方式来提升性能不必考虑其它模块的情况
缺陷 #
- 运维要求较高
- 对于单体架构来讲,我们只需要维护好这一个项目就可以了,但是对于微服务架构来讲,由于项目是由多个微服务构成的,每个模块出现问题都会造成整个项目运行出现异常,想要知道是哪个模块造成的问题往往是不容易的,因为我们无法一步一步通过debug的方式来跟踪,这就对运维人员提出了很高的要求
- 分布式的复杂性
- 对于单体架构来讲,我们可以不使用分布式,但是对于微服务架构来说,分布式几乎是必会用的技术,由于分布式本身的复杂性,导致微服务架构也变得复杂起来
- 接口调整成本高
- 比如,用户微服务是要被订单微服务和电影微服务所调用的,一旦用户微服务的接口发生大的变动,那么所有依赖它的微服务都要做相应的调整,由于微服务可能非常多,那么调整接口所造成的成本将会明显提高
- 重复劳动
- 对于单体架构来讲,如果某段业务被多个模块所共同使用,我们便可以抽象成一个工具类,被所有模块直接调用,但是微服务却无法这样做,因为这个微服务的工具类是不能被其它微服务所直接调用的,从而我们便不得不在每个微服务上都建这么一个工具类,从而导致代码的重复