聊聊微服务到底该如何划分

f6a8069035eb224d09b1373bba2befee.jpeg

背景

        现在动不动就是微服务架构,但是微服务划分的合理与否会极大的影响开发过程中的复杂度,划分的重要性不言而喻,但是在微服务划分这条路上并没有银弹,有的说DDD可以解决微服务的划分问题,吕哥想说的是那只是理论上的,实际上影响微服务划分的因素众多,不能死搬教条,每个项目都有自己的特点和实际情况,我们要做的把理论与实际结合,把知识融会贯通,走“自己特色的项目道路”.

一、单体系统分解成微服务系统,如何划分最合理,为什么?

ea10304b7072732c7f5a6fa8080facfb.png

简单说的话就是:找到合理的划分边界,把每一个功能每一个接口每一个类放到最合适的服务中,使划分后的服务之间满足”高内聚,低耦合,同时要兼顾职责单一,代码复用率高“,这并不是一件容易的事情,难就难在影响的因素太多(技术因素、业务因素、人为利益因素,甚至受到公司部门斗争人情世故的影响),死搬教条是行不通的,一定要在基本正确的前提下不断改进与重构,向着最优解靠近。

“高内聚低耦合”意味着服务独立性高,依赖关系简单,那么复用率会受到什么影响呢?我之前写过关于“聊聊代码复用的文章”,复用的种类主要分两种情况:

1)集成式的JAR包复用;

15fcc6bb158241937de0924a094e05d5.png

2)RPC式的接口复用;

b4d12b382716498ac3d0247e900cd4d1.png

“高内聚低耦合” 对于集成式JAR包复用我认为没有影响,对于RPC式的接口复用意味着 复用率降低,但这同时也是低耦合的表现,不一定是坏处,这里面就需要一个平衡。

对于项目经验较少的同学来说,以上说法还是很抽象的,下面吕哥通过曾经的项目经历来剖析微服务化后带来的复杂性。

二、单体系统微服务化后到底会遇到什么问题?

1、数据库纵向拆分

微服务要求每个服务都有独立的数据库,跨服务的SQL联查会全部失效,如何解决?

21d9c03f27976eb01fb6b5aec5c36eae.png

SQL联查意味着表之间是有关联性、依赖性、耦合性的,现在虽然数据库进行了物理隔离,但是这种业务上的关联性仍然是需要解决的,如何解决呢?

方案1)

关联逻辑转移到服务代码层,将复杂查询SQL拆解,属于自己服务管理的部分直接查库,属于别的服务管理的部分通过RPC查询,最后在内存中计算组合得到最终想要的结果;

4653153ec4e841ff8af4757177282e09.png

方案2)

主库数据冗余,冗余的粒度可大可小,大则整张表冗余,小则按列进行冗余。无论哪种方式都需要解决数据的实时性和数据一致性问题;

d07376a779197e7f387d29222a588491.png

方案3)

数据集中到只读数据仓库中,再进行跨域SQL查询,同样需要解决数据的实时性和数据一致性问题;

d4d7a4eba182e96726e0f51237583be7.png

2、分布式事务

微服务化后会产生RPC操作,由此产生的分布式事务(数据一致性问题)如何解决?

系统之间交互无非两种模式:

1)同步通信

e6303e6758e1dd1c94f8271a3dea43c9.png

2)异步通信

2a2ffd9f9477361c1354b4223ba1050f.png

哪些业务需要同步通信,哪些业务可以接受异步通信?

同步通信模式下如何解决分布式事务问题?

1)SEAT框架AT模式

586345f10faa35ce54b0dc4142e57d96.png

2)TCC框架

f185e062bccfad46157e76b2b81a9489.png

3)SAGA框架

e0eb74078d95be3a8223971bdef32aa3.png

异步通信模式下如何解决分布式事务问题?

1)消息队列

303dd27ab743fe181198b8af635d2d6e.png

8f9e67f2171ea6e591d67cf946e49fce.png

2)定时任务

f7243a32b0e08c598df222a966fb247f.png

62b018c9e1cddb7c9a3eec89c25cd9d2.png

3、服务依赖

如何解决领域存活问题?服务雪崩问题?

对于同步通信模式下,领域存活会受到挑战,一般只能通过功能降级来应对;受接口堵塞的影响雪崩问题会接踵而来,一般通过限制接口超时时间、限制重试次数、接口熔断来解决;

fa1dd4cdd491c8c99fba13d74ddb93c9.png

对于异步通信模式下,领域存活不会受到影响,也不会有雪崩问题,但是业务的进度会受到积压。

c7297066ba294f4df3fe39b8e6f10781.png

4、服务的主次之分

01dc45d2f96d49ecf4ecb05d14d27be3.png

核心服务:影响全局服务的基础服务(如:ID生成服务)、影响关键路径的服务(如:登录服务)

重要服务:主要业务所在的服务,用户大部分时间都是在这个服务上操作的,如:商品查询、订单提交、订单支付

次要服务:辅助性的服务,售后服务、退货退款、发票服务、报表统计

对于核心服务是要保障三高的,它影响的是全局;

对于重要服务是要保障领域独立存活的,影响最小化,即使支付服务挂了,也不能影响 商品查询和订单提交等服务;

次要服务在遇到故障或资源紧张的情况下是可以降低资源投入或者临时关闭的;

三、总结

1、以服务的“高内聚,低耦合,兼顾职责单一,代码复用率高”为指导原则;

2、可以参考DDD领域驱动设计的方法论;

3、服务的拆分影响因素很多,包括团队技术水平、业务水平、人为因素、部门斗争、康威定律;

4、不要死搬教条,要不断地思考、改进重构、及时修正错误 才能达到一个相对理想的效果;

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吕哥架构

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值