微服务的微
亚马逊的掌门人:双披萨原则(这个原则的本质就是建议保持小规模团队)
对于微服务的划分,什么粒度的微服务才是合适的?这个没有标准答案
支持外部业务压力的漏斗
动静分离(CDN)—>扩容(负载均衡)—>缓存(热数据Redis/搜索ES)—>服务降级—>限流
并不是你的项目中使用了微服务的开源技术,你的项目就是一个微服务架构了
所有的微服务中间件都是外功,什么是内功?
第一个核心:拆
微服务最直观的感受就是一个字:拆,应用微服务的第一步就是理清两个问题:拆什么?怎么拆?
业务架构、应用架构、技术架构、数据架构
单一职责
对于微服务结构:最适合的才是最好的,拆分的过程中的领域划分和粒度还是要结合自身业务进行考量
单一职责不仅涉及到服务拆分,在微服务领域,这种职责划分还涉及:数据库、开发、测试、发布运维都划分到一个领域模型中
研发团队赋能
研发团队要充分授权
可独立部署
每个微服务模块都应该可以独立打包,独立部署的应用
接口间调用要有过度方案
独立部署的问题:做全链路的end-to-end测试非常困难而且回归耗时,你的改动有可能导致上下游团队的系统BUG
一般是通过Nginx实现反向代理来做负载均衡,通过众多的Web服务器实现HA集群,这些服务器都是通过N+1的方式进行部署
数据访问杂乱问题
各个应用访问数据都是直接连接数据库的,通过各种join连接,数据模型变动会带来很多的业务变更影响
通过微服务架构隔离变更影响,让其在自己的领域中进行变更处理
底层组件变更
对于底层数据库变更,比如oracle换成MySQL,亦或改成MyCat或sharding-jdbc这种方式,这个时候业务就会出现较大的变动影响
通过微服务将底层的业务领域模块抽离出来进行API接口+业务模型方式对外提供服务,这就是能在对应的领域模型里进行变更和修改了。
代码复用带来的维护成本
快速上线抢占时间窗口
短猛急的研发方式
快速迭代:尽快上线,在这个场景下,对于微服务的领域模型来讲就再适合不过了
异常回滚:对于微服务架构,回滚只局限在某个微服务范围内,只要把有问题的模块回滚掉就ok了,不会影响其他模块的发布节奏,但要考虑模块间的依赖关系,还要考虑一下下游依赖
微服务的拆分没有一个绝对正确的答案,服务的拆分粒度要完全根据业务场景来规划,但随着业务的不断推进,原先的拆分方案也要做调整,可以参考一以下维度和模式
压力模型简单来说就是用户访问量,我们识别出超高访问量的业务,将这些业务拆分出来,如果不拆分,高压力业务就会导致整个服务挂掉,我们肯定不希望让这种情况影响到其他业务
举两个例子:
在具体规划的时候,尽量把压力模型拆解为以下三个维度
通常建议将高频高并发的场景单独拆出来,对于低频高并发的如果允许的情况下单独拆出,如果不能独立需要考虑流控以及补偿。
主要从这三个维度考虑:主链路、领域模型、用户群体
什么结果是这个系统产生的前提,这个结果产生的流程就是系统的主链路
在业务系统拆分和保障的过程中一定要确保主链路可用
DDD(Domain-Driven Design)领域驱动设计
所谓领域模型其实就是一套各司其职的服务集合
我们在做微服务架构拆分的时候要确保我们的各个领域之间有清晰的界限
首先要了解系统有哪些用户,比如电商系统有买家、卖家,根据用户来进行前台后台业务系统的系统
前后台业务应用区分
微服务的优点
微服务架构设计的缺点
通过对微服务的优缺点理解可以得出:
业务规模要有一定的量,也就是成本和收益的博弈过程决定了是否做微服务改造
业务架构和领域模型的理解决定了我们怎么做微服务,如何拆分和拆分的粒度大小
对于业务流量非常大的场景下,我们拆分后的微服务可以要调用多个微服务模型,这么多的服务哪个可用,哪个不可用,什么时候上线什么时候下线,服务的扩缩容都要很清楚的明白,这就是服务治理
在服务治理的场景下还需要负载均衡解决服务节点的访问问题
在服务不可用的情况下,下游服务要能够提供容错机制,就是服务的降级和熔断
大家在平时的项目中是怎么管理配置项的?使用配置文件?对于配置文件我们需要一个公共的配置中心来统一管理
通过微服务架构中服务的转发
对于最终的数据结果差异,在微服务架构里很难进行数据追踪查询错误
RabbitMQ和kafka在调用的时候调用方式和ACK机制一样吗?通过一个公共的收发消息的模块来进行底层消息调用
我们需要在微服务阶段引入分布式限流的手段
我们应该选择哪些技术组件来组合实现微服务架构并完成微服务的改造,有没有一套业界的最佳实践来参考一下呢?答案是有的!
spring整合了各路优秀的开源组件,打包提供了一套最佳业界实践的解决方案组件集合,他就是微服务领域的圣经:springcloud(春云)
主要的两个组件来源地:Netflix和Alibaba
所有上面提到的这些微服务面临的技术问题都可以通过springcloud提供的组件进行简单的注解和配置实现并应用到系统中
springcloud的生态系统的建立
Netflix
Alibaba
Spring Open Source
2015.3 Angel
2016.5 Brixton
2016.9 Camden
2017.4 Dalston
2017.11 Edgware
2018.6 Finchley
2019.1 Greenwich
2019.11 Hoxton SR3
SpringCloud的版本升级的利弊权衡
项目技术栈升级,推荐方式
就一个字:拆
贫血模型vs领域模型
什么是贫血模型?几乎80%的项目使用的都是贫血模型
所谓贫血模型,就是指Model中仅包换属性,不包含行为,采用这种设计时,需要分离出DB层(mapper/dao)专门用于数据库的操作(数据库作为状态数据的存储方)
典型的包结构:
po/bo/pojo;放的实体对象或持久化对象,仅包含属性和Get/Set方法,没有行为方法
dao/mapper:存放对数据库的访问的方法
service:存放业务行为实现
controller;提供对UI层访问的入口
贫血模型的优点很明显:
1、被许多程序员掌握,许多教材采用的都是这种模型,对于初学者使用这种模型很自然,甚至很多程序员认为这才是最正统的业务模型
2、它非常简单,对于不复杂的业务,工作的很好开发也迅速,只需要知道功能实现步骤就可以实现了
3、事务边界相当清晰,一个service的每个方法都可以看作是一个事务,Service的每个方法都对应一个用例
缺点也非常明显
1、所有业务都在service里维护,当业务越来越复杂,service会变得非常大,最终难以理解和维护
2、将所有业务放在无状态的service中实际上是一种面向过程的设计,他在组织复杂业务时存在天然劣势,随着业务的复杂度提升,业务会在service中多个方法间互相调用
3、当添加一个新的UI时,往往需要重新编写业务逻辑
一般包含如下包结构:
**infrastructure:**代表基础设施层,为其他各层提供基础资源服务,例如缓存,DB,网关服务
**application:**代表应用层,提供UI层的访问接口,作为事务的界限。实现服务的组合和编排
**domain:**代表领域层,domain包含两个包:model和service,model中包含模型对象和业务功能,service中包含一系列的领域服务,对于模型对象的分析不便放入某个模型对象中,就可以放入领域服务中
领域模型的优点:
1、领域模型采用OO设计,将业务行为落地真正的Model中,可以进行充分的服务编排
2、从领域的业务模型上做了分层和抽象,将核心业务逻辑做了统一,然后进行服务编排即可
领域模型的缺点:
1、对程序员的要求比较高,初学者对这种职责分配到多个协作对象中的方式极不适应
2、领域驱动建模要求对领域模型完全了解,只给出一个用例来实现领域模型是无法做到的,在建模初期需要和领域专家(业务方,需求方)充分沟通,错误的领域模型对项目的危害非常大,实现一个好的领域模型比较困难
3、对于简单的系统,使用领域模型杀鸡用牛刀了