在我的项目中目前是有网关、认证、文章、会话、消息、通知、评论、关注、点赞、用户信息。

尽可能细

之所以这么分其实是按照数据库表来构建的,除了网关、认证其他都有直接对应的表,网关和认证是OAuth2的密码模式发放JWT来实现单点登录。我在设计时还认为这是一个整体的应用即整体的就是一个系统,认证就只负责认证,鉴权的解析放在网关。

在一位老哥听我介绍完项目后问我为什么把鉴权的解析放在了网关而不是把 认证鉴权放在一起作为一个基础服务给网关调用。

微服务拆分策略和原则 微服务拆分方案_微服务拆分策略和原则

 业务简单时拆分反而导致开发成本比单体应用更高。业务复制时拆分可以提高系统可用性并便于单服务测试。

服务分级

一开始我还不太理解我认为不管是网关还是什么能通过部署在更多机器上实现整体系统的性能提高就是微服务。之后意识到这个系统中可能不止存在一个应用,可能有多个应用而且每个应用都有单独的网关,那么如果是多个网关得情况下鉴权的逻辑就要在每一个应用的网关中实现一遍。

这种账户登录权限作为一个账户系统应该作为一个基础能力合并在同一个服务中。

类似的基础能力在我的系统中还有消息推送能力,之前在最开始设计时只考虑聊天消息的推送,就把实现推送的代码写到了消息服务中,而之后写完了想到还有通知、点赞、关注都需要推送给用户。

推送就应该抽出作为一个服务,提供推送能力给上层业务调用。

作者:方丈的寺院

横向: 按照业务流程拆,业务流程反映的是数据流程,数据从上游流下下游。上游需要和下游解耦,上游不可通过服务间调用下游。下游可以。

纵向: 按照技术拆分,由上到下分为4层,上层可以调用下层,同级可以相互调用,下层强制不能调用上层。

1. 应用系统 面向各个端,比如pc端,面向用户的,面向小二的。app端。属于前端应用。

2.核心领域 整个系统的核心业务,与业务紧密相连。支撑业务发展。

3.基础能力 从核心领域中下沉抽象出来的更通用的服务,不只是服务当前业务。也服务于公司其他业务。

4.依赖系统 一些通用的公共模块以及与其他兄弟部门的服务依赖。

如此调用关系比较清晰了。

微服务拆分策略和原则 微服务拆分方案_java_02

拆分原则

作者:十一技术斩

1. 单一服务内部功能高内聚低耦合

也就是说每个服务只完成自己职责内的任务,对于不是自己职责的功能交给其它服务来完成。

2. 闭包原则(CCP)

微服务的闭包原则就是当我们需要改变一个微服务的时候,所有依赖都在这个微服务的组件内,不需要修改其他微服务。

3. 服务自治、接口隔离原则

尽量消除对其他服务的强依赖,这样可以降低沟通成本,提升服务稳定性。服务通过标准的接口隔离,隐藏内部实现细节。这使得服务可以独立开发、测试、部署、运行,以服务为单位持续交付。

4. 持续演进原则

在服务拆分的初期,你其实很难确定服务究竟要拆成什么样。从微服务这几个字来看,服务的粒度貌似应该足够小,但是服务多了也会带来问题,服务数量快速增长会带来架构复杂度急剧升高,开发、测试、运维等环节很难快速适应,会导致故障率大幅增加,可用性降低,非必要情况,应逐步划分,持续演进,避免服务数量的爆炸性增长,这等同于灰度发布的效果,先拿出几个不太重要的功能拆分出一个服务做试验,如果出现故障,则可以减少故障的影响范围。

5. 拆分的过程尽量避免影响产品的日常功能迭代

也就是说要一边做产品功能迭代,一边完成服务化拆分。比如优先剥离比较独立的边界服务(如短信服务等),从非核心的服务出发减少拆分对现有业务的影响,也给团队一个练习、试错的机会。同时当两个服务存在依赖关系时优先拆分被依赖的服务。

6. 服务接口的定义要具备可扩展性

服务拆分之后,由于服务是以独立进程的方式部署,所以服务之间通信就不再是进程内部的方法调用而是跨进程的网络通信了。在这种通信模型下服务接口的定义要具备可扩展性,否则在服务变更时会造成意想不到的错误。比如微服务的接口因为升级把之前的三个参数改成了四个,上线后导致调用方大量报错,推荐做法服务接口的参数类型最好是封装类,这样如果增加参数就不必变更接口的签名,而只需要在类中添加字段就可以了

7. 避免环形依赖与双向依赖

尽量不要有服务之间的环形依赖或双向依赖,原因是存在这种情况说明我们的功能边界没有化分清楚或者有通用的功能没有下沉下来。

微服务拆分策略和原则 微服务拆分方案_微服务拆分策略和原则_03

8. 阶段性合并

随着你对业务领域理解的逐渐深入或者业务本身逻辑发生了比较大的变化,亦或者之前的拆分没有考虑的很清楚,导致拆分后的服务边界变得越来越混乱,这时就要重新梳理领域边界,不断纠正拆分的合理性。