单体的优缺点前端
单体应用就是将应用程序的全部功能都打包成一个独立的单元,最终以一个WAR包或JAR包存在,没有外部的任何依赖,里面包含DAO,Service、UI等全部的逻辑。单体应用有如下优势:java
不幸的是,这种简单的单元有很大的局限性。应用程序随着业务需求的迭代,功能的追加扩展,最终成为一个庞然大物。变得更加复杂,逻辑耦合严重,难以理解,团队开发 人员职责不清,部署困难,回归测试成本巨大,交付效率大大下降,总结下来,单体应用有一下缺点:redis
1. 复杂性高sql
代码难以理解
在业务规模和团队规模发展的必定阶段,这些不足表现的更加明显,单体架构的不足首先表如今复杂性上, maven模块增多,多个模块耦合在一块儿,代码结构混乱,使得团队成员没有一我的理解整个代码逻辑;数据库
难以理解致使代码质量低,复杂性进一步增长
难以理解致使代码复用度下降,由于你不知道哪些能够复用的;即使修改,影响范围也很差肯定,这致使这样开发宁愿新建一个新方法和新的类,进一步致使重复代码越积越多;后端
2.交付效率低api
全量部署耗时长、影响范围广、风险大,发布频次低
正由于这种全量部署耗时长、影响范围广、风险大,致使咱们将不少功能和修复汇集在一块儿进行开发完成,这致使了产品发布频次下降,新的功和更换的体验能不能及时呈现给用户,甚至被竞争对手赶超。
3.伸缩性(scalable)差浏览器
单体只能按总体横向扩展,没法分模块垂直扩展安全
IO密集型模块和CPU密集型模块没法独立升级和扩容
业务模块对资源的需求是不同的,因为全部模块部署到一块儿,单体架构IO密集型模块和CPU密集型模块没法独立升级和扩容的,好比图片压缩,加解密这些 都是cpu资源密集的应该升级CPU,而IO密集型的模块好比日志收集服务IO操做比较多须要更大的内存,使用好比SSD性能更好的磁盘。
4. 可靠性差性能优化
一个bug有可能引发整个应用的崩溃
因为全部模块都是部署在一个实例中,一个bug会引发整个应用的崩溃,好比一个不重要的模块的内存泄露就将会致使全部应用实例一个个crash掉
5.阻碍技术创新
那么如何解决单体的不足呢,经过迁移到微服务架构来解决,咱们看一下什么是微服务。
微服务的定义
微服务架构:将单体应用拆分为多个高内聚低耦合的小型服务,每一个小服务运行在独立进程,由不一样的团队开发和维护,服务间采用轻量级通讯机制,独立自动部署,能够采用不一样的语言及存储。
咱们经过上图来看下单体架构到微服务架构的对比。此图是一个简单电商单体到微服务架构的演进图,单体架构整个团队维护开发一个大工程及一个单库,到了微服务架构,用户请求通过API Gateway被路由到下游服务,服务之间以轻量级通讯协议进行通讯,服务经过注册中心发现彼此,每一个服务都有专门的开发维护团队,每一个服务对应独立的数据库,服务独立开发,独立部署和上线。 接下来咱们总结下微服务的优势。
微服务的优势
易于开发与维护
微服务的挑战
没有任何技术是银弹,微服务也是如此 ,都或多或少有一些缺点和问题。那么咱们就必须针对这些问题一一解决,也是咱们接下来章节重点去作的. 我首先面对就是要将单体拆分红多个服务。
1.服务拆分
微服务拆分原则:领域模型、限定上下文、组织架构、康威定律
现实中没有一个具体明确的方法能够将拆分一步到位,而是遵照必定的原则,好比根据领域模型、组织架构、单一职责这些进行拆分在拆分的过程当中还要结合经验判断,而且随着需求迭代,架构持续优化演进,优化服务的拆分。
每一个微服务拥有独立数据库
服务拆分的同时还要考虑到存储数据库也要独立,当多个服务直接读写数据库中同一张表时,对这些表作任何改动都须要协调这些相关服务的部署。这一点违背了服务相互独立这一原则。共享的数据存储很容易不经意间形成耦合。每一个服务须要有本身的私有数据。好比订单表被订单服务和商品服务所共享,商品服务单独作统计并不知道本身一天多少商品被卖出,不知道哪些数据由本服务产生的,就没法进行技术产品规划,对表结构的修改也要通知多个服务,这是所不能容忍的。每一个服务须要本身的数据库,但这些数据库可共置在一台共享的数据服务器上,数据库私有的重点在于不该让服务知道其余服务底层数据库的存在。可用一台共享数据服务器先开始开发,之后若是数据量和并发量变大,服务器能够进行隔离。服务器隔离后,只要更改配置便可将不一样服务的数据库隔离起来。
微服务之间肯定服务边界,经过共享模型创建联系
每一个微服务都具有本身的业务能力,那么服务之间交互的部分便是服务边界; 肯定服务边界也是一个难题,须要对本身的产品和业务有足够的了解才能肯定最天然的服务边界肯定服务边界坚持的原则是要高内聚弱耦合,弱耦合就是一个服务与其余服务的任何通讯都应经过公开暴露的接口(API、事件等)实现,这些接口须要妥善设计以隐藏内部细节。这样咱们的服务之间保持独立,在将来咱们能够轻松重构,高内聚力就是密切相关的多个功能应尽可能包含在同一个服务中,这样可将服务之间的干扰降至最低。
2.数据一致性
在单体架构中,咱们经过数据库事务完成的操做 放在分布式微服务架构下没法完成了,由于实例被部署不一样服务器上,好比订单服务进行下单操做,下单操做和扣减库存应该放在同一个事务中,在微服务架构下,下单操做和扣库存操做被分布在不一样服务器上,就须要进行分布式事务操做,而分布式事务具备延迟较高、nosql数据库不支持等缺点。这些缺点致使分布式事务没法应用到微服务中在微服务场景下,咱们一般使用最终一致性来代替强一致性。
3.服务通讯
4.服务网关
5.高可观察
6.可靠性
在讲单体的过程当中,咱们讲到,一个业务模块的内存泄露会致使整个进程退出。 在微服务场景下,若是一个服务出现内存泄露是不会影响 没有依赖关系的服务的。 可是却能够由于该异常服务的僵死或不可用形成上游服务线程hang住,进而产生级联效应,故障进一步向上游传播。
提炼代码脚手架
除了开发业务逻辑,咱们还须要搭建一套微服务工程可用框架,这样是是为了加快团队工做效率,微服务解决方案保持统一,加强代码复用性,统一进行优化,微服务要解决的问题很是多,因此抽取服务代码模板是有必要的,它包括服务注册发现、服务通讯、监控、日志、异常处理等等。
从单体迁移到微服务
咱们先看这张图,这张图是从一篇外文中摘出来的,连接已经编辑在图片中; 绿线表明单体架构,蓝线表明微服务架构,X轴表明复杂度,Y轴表明生产效率。
当业务不复杂,团队规模不大的时候,单块架构比微服务架构具备更高的生产率(productivity),由于创建微服务架构须要额外的开销来支持和管理微服务, 从而下降生产率;可是随着业务复杂性的增长和团队规模的扩大,单块架构比微服务架构的生产率降低更趋明显, 当复杂性达到一个临界点,微服务架构的生产率会优于单块架构, 由于微服务的松散耦合自治特性减缓了生产率的降低趋势。
因此咱们在作项目时,必定要根据本身的团队和业务复杂性来判断,什么时候应用微服务。 以个人经验给你们的建议时,一个全新项目在1-3团队时,能够先拆分红一个API 网关和一个集合全部业务的后端服务,API网关关注鉴权和路由、处理部分失败;后端服务要划分好业务模块;项目初期,因为流量很少,能够没必要添加流量控制和断路器等组件。
同时即便向微服务架构迁移以后,拆分的粒度也要由粗到细演进式发展,必定要根据本身的业务规模复杂性和团队规模来定。
一个策略是:不要大规模(big bang)重写代码(只有当你承担重建一套全新基于微服务的应用时候能够采用重写这种方法)。重写代码听起来很不错,但实际上充满了风险最终可能会失败,就如Martin Fowler所说:“the only thing a Big Bang rewrite guarantees is a Big Bang!”
相反,应该采起逐步迁移单体式应用的策略,经过逐步生成微服务新应用,与旧的单体式应用集成,随着时间推移,单体式应用在整个架构中比例逐渐降低直到消失或者成为微服务架构一部分。这个策略有点像在高速路上限速到70迈对车作维护,尽管有挑战,可是比起重写的风险小不少。
Martin Fowler将这种现代化策略成为绞杀应用,名字来源于雨林中的绞杀藤(strangler vine),也叫绞杀榕(strangler fig)。绞杀藤为了爬到森林顶端都要缠绕着大叔生长,一段时间后,树死了,留下树形藤。这种应用也使用同一种模式,围绕着传统应用开发了新型微服务应用,传统应用会渐渐退出舞台。
SOA VS 微服务
SOA和微服务的对比是一个老生常谈的话题,我认为二者最大的不一样是提出时所处的技术背景和环境。
SOA的出现实际上是为了解决历史问题:企业在信息化的过程当中会有各类各样互相隔离的系统,须要有一种机制将他们整合起来,因此才会有ESB的出现。一样的,也成了SOA初期的服务是很大的概念,一般指定的一个能够独立运做的系统。
微服务没有历史包袱,服务的尺寸一般不会太大,从服务粒度来说,SOA更像是单体的简单组合,而微服务是粒度更细小的服务,其次数据拆分SOA倾向于共享数据库,微服务一个服务对应一个数据库。
微服务知识全景图
微服务知识全景图会在课程《Java深刻微服务原理改造房产销售平台》中介绍和实践。