QCon2016参会感悟:微服务架构演进
前不久参加2016年QCon,针对 "服务架构演进" 的有所感悟,会后针对演进各阶段的特点汇总如下。
阶段一:单体应用(Monolith Application)
这是早期的Wed应用开发方式,通常MVC层、Service层和ORM层整合在同一个Web应用中,在遭遇流量压力时,只能进行简单的机器集群。一个典型单体应用结构如下图所示:
概念:将应用程序的所有功能都打包成一个独立的单元,可以是JAR、WAR、EAR或其它归档格式。
优点 | 解释 |
---|---|
1、为人所熟知 | 现有的大部分工具、应用服务器、框架和脚本都是这种应用程序 |
2、IDE友好 | 像NetBeans、Eclipse、IntelliJ这些开发环境都是针对开发、部署、调试这样的单个应用而设计的;至今没有一款天然为远程服务调用设计的IDE; |
3、便于共享 | 单个项目归档文件包含所有功能,便于在团队之间以及不同的部署阶段之间共享; |
4、易于测试 | 单体应用一旦部署,所有的服务或特性就都可以使用了,这简化了测试过程,因为没有额外的依赖,每项测试都可以在部署完成后立刻开始; |
5、容易部署 | 只需将单个归档文件复制到单个目录下,如Tomcat,即可完成部署,不依赖第三方业务; |
伴随业务发展,缺点之间暴露,复杂而巨大的单体式应用也不利于持续性开发,缺点如下。
缺点 | 解释 |
---|---|
1、代码重复率高 | 各个单体应用,公共模块重复开发、重复维护; |
2、需求变更困难 | 不够灵活:对应用程序做任何细微的修改都需要将整个应用程序重新构建、重新部署。开发人员需要等到整个应用程序部署完成后才能看到变化。如果多个开发人员共同开发一个应用程序,那么还要等待其他开发人员完成了各自的开发。这降低了团队的灵活性和功能交付频率;臃肿的部署,整个应用; |
3、妨碍持续交付 | 无法满足新业务快速创新和敏捷交付:单体应用可能会比较大,构建和部署时间也相应地比较长,不利于频繁部署,阻碍持续交付。在移动应用开发中,这个问题会显得尤为严重; |
4、功能孤岛 | 传统的MVC架构、本地代码不断迭代、垂直的功能孤岛;最终演化成调用关系只有原作者可读懂,直至腐化失传;团队接手困难,单体逻辑复杂; |
5、共生共灭 | 垂直应用越来越多》测试、部署成本高,可伸缩性差, 可靠性差,影响单体应用内其他业务逻辑,共生共灭; |
6、局限的弹性与扩展能力 | 强耦合的整体;耦合:MVC、Service和ORM层耦合; |
7、阻碍技术革新 | 单体应用技术选型单一;受技术栈限制:对于这类应用,技术是在开发之前经过慎重评估后选定的,每个团队成员都必须使用相同的开发语言、持久化存储及消息系统,而且要使用类似的工具,无法根据具体的场景做出其它选择; |
8、技术债务 | “不坏不修(Not broken,don’t fix)”,这在软件开发中非常常见,单体应用尤其如此。系统设计或写好的代码难以修改,因为应用程序的其它部分可能会以意料之外的方式使用它。随着时间推移、人员更迭,这必然会增加应用程序的技术债务。 |
最终,导致以下问题。
那么,如何解决 “单体应用” 问题呢?
系统需要做到:分层、解耦、拆分、独立;
阶段二:面向服务架构(SOA)
这是目前业界比较流行的架构模式,通常根据业务职责划分为多个系统,系统之间的交互以服务的方式进行。
概念:Service-Oriented Architecture,将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。
通常需要接入RPC中间件,如Dobbo、Thrift等;
优点 | 解释 |
---|---|
1、分层 | 抽象核心服务和业务服务等,形成公共服务; |
2、独立 | 服务可以独立打包、发布、部署 |
3、服务可伸缩 | 可以有针对性的进行单个服务的扩容; |
4、专注性 | 屏蔽底层复杂度 |
5、资源重用 | 提供有限接口,无限性能; |
6、系统解耦 | 不同业务功能拆分不同系统,避免耦合; |
7、透明调用 | 封装底层通讯细节,向调用本地方法一样调用远程服务; |
8、SQL 质量得到保障 | 有了服务层之后, 所有的 SQL 都是服务层提供的,业务线不能再为所欲为了 |
9、数据库解耦 | 底层例如数据库连接到达上限系统共用的底层资源在随着机器增加的越来越多时,一定会成为瓶颈,这种情况下服务化会带来帮助 |
10、敏捷交付 | 开发人员规模庞大当开发人员规模变大(100个左右)时,众多人共同维护一个系统会变得不可行,这个时候服务化可以产生巨大帮助,也会成为必须做的事情。 |
虽然SOA解决了单体服务的痛断,但是又引入许多新的问题,如下:
缺点 | 服务化不是银弹!警惕“单体服务”! |
---|---|
1、耦合部署 | 单体服务内部,各个服务在代码、发布时耦合; |
2、运维效率低 | 一个需求设计多个项目,需要发布多个项目; |
3、提升系统复杂度 | 服务注册发现、限流、降级(熔断)、故障隔离等; |
4、服务依赖 | 业务稳定性依赖第三方服务; |
5、学习成本 | 存在一定上手难度 |
6、时延问题 | 服务通讯增加了额外的系统负责度,以及性能开销; |
7、问题定位 | 分布式环境,高效快速定位问题 |
8、事务一致性 | 逻辑关联的几个连续数据库操作被打散在不同服务中,最终一致性,消息加轮训,try-confirm-cancel; |
9、难以重构 | RPC私有协议,并非浏览器友好, |
10、多团队进度协同问题 | 需要等待以来的服务方提供服务API才可以进行开发 |
11、接口前向兼容性问题 | 服务以API方式发布,必须要兼容老版本API不受影响 |
12、基础设施&团队要求高 | 企业的基础设施以及团队要求也比较高 |
当SOA带来的上述问题越来越尖锐时,同样将导致一些结果:
那个该如何解决上述问题呢?
需要我们进行 “有效的服务拆分”
阶段三:微服务(Micro Services)
我们重点关注标红的部分:一系列小服务、各自运行在单独的进程、围绕各自业务功能、独立部署、最低限度的集中管理;
概念/优点 | 解释 |
---|---|
1、有效拆分 | 有效的拆分应用,实现敏捷开发和部署; |
2、独立部署(服务自治) | 将应用程序设计成一套可以单独部署的服务。原子粒度:服务拆分粒度:SOA首先要解决的是异构应用的服务化;微服务强调的是服务拆分尽可能小,最好是独立的原子服务; |
3、避免依赖 | 传统的SOA服务,由于需要重用已有的资产,存在大量的服务间依赖;微服务的设计理念是服务自治、功能单一独立,避免依赖其它服务产生耦合,耦合会带来更高的复杂度; |
4、敏捷运维 | 传统SOA服务粒度比较大,多数会采用将多个服务合并打成war包的方案,因此服务实例数比较有限;微服务强调尽可能拆分,同时很多服务会独立部署,这将导致服务规模急剧膨胀,对服务治理和运维带来新的挑战; |
5、敏捷交付 | 服务由小研发团队负责微服务设计、开发、测试、部署、线上治理、灰度发布和下线,运维整个生命周期支撑,实现真正的DevOps。 |
服务化虽然拥有以上优点,但是万物具有两面性,同样会带来以下问题:
缺点 | 微服务不是银弹! |
---|---|
1、服务数量激增 | 微服务化之后,服务数量的激增会引起架构质量属性的变化; |
2、调用链路变长 | 服务拆分粒度更小必然导致调用链变长,远程服务通讯次数更多 |
3、服务监控复杂 | 调用链增长,需要监控的调用链更长 |
4、基础设置 | 为了保证高性能、低时延,需要高性能的分布式服务框架保证微服务架构的实施;自研服务框架还是使用开源的方案; |
5、迁移成本,人员技能培训成本 | 评估迁移的工作量,以及人员技能培训等 |
6、适用范围 | 当前单机应用是否能够满足业务发展需要,有没有必要做服务化改造和分布式部署; |
微服务拆分粒度:
- 1、功能完整、职责单一,这是理想的拆分原则,但是完全按照功能拆分,可能会导致服务数量激增,需要权衡得失;
- 2、粒度适中,团队可接受:这是推荐的拆分原则,通常一个微服务对应一个业务开发团队,在团队业务内适当放宽粒度可以提高开发效率和体验;
从上文总结,微服务演进经历有 "单体应用 》 服务化 》 微服务" 等流程,如下图所示:
参考
- 《电商 CRM 的微服务重构实践》阿里巴巴客户体验事业群高级技术专家 邱小侠
- 《大型企业云平台架构和关键技术实践》华为软件云平台资深架构师 苗彩霞
- 《滴滴代驾微服务架构演进》滴滴代驾事业部架构师 赵伟
- http://www.tuicool.com/articles/Qr2q6z3
- http://www.infoq.com/cn/news/2015/04/single-app-micro-service/
- https://my.oschina.net/zhanghaiyang/blog/725728
转载于:https://my.oschina.net/xuxueli/blog/782478