在做微服务设计的时候,很大的一个难题就是服务的拆分,很多人都不知道在什么情况拆分服务,在什么情况下不应该拆分服务,所以设计的系统可能会很臃肿,如果遇到业务扩展,之前设计的架构不能满足业务扩增后的需求,就会面临重构的风险,因此,在设计微服务架构时,合理的服务拆分是十分重要的。

前提

在做拆分服务之前,有一点特别重要,系统设计应该根据当前的用户情况而设计。如果目前用户不多并且增长比较慢,那么设计那些大而宽的架构并没有什么意义,单体服务就可以搞定,成本也比较小,并且可以满足早期的迅速开发和业务迭代需求,如果用户进一步扩大,那么再考虑优化架构的事。如果用户规模比较大,并且增长比较快,那么这个时候就应该考虑大请求量时的系统设计。因此,在做系统设计时,有一点很重要,避免过早的优化。

怎么拆分服务

服务的拆分应该要考虑这几个方面:

  • 单一职责
  • 业务拆分粒度
  • 避免互相依赖
  • 有状态和无状态分离
  • 避免引入分布式事务问题

虽然这几点看起来很简单,但是实际上做起来会遇到很多问题,因为需求是不断变化的,可能随着时间的累计,不停的在服务上堆功能,原本互不依赖的服务开始慢慢互相依赖,这样会给系统升级带来很大的风险。

其次,不同服务之间的业务可能会存在对相同数据的依赖,如果共享数据库,当对数据库进行更改时,影响的服务会很多。如果不共享数据库,服务通过rpc接口获取数据,这样服务之间会产生依赖,甚至循环依赖,这样的话继续扩展是件很痛苦的事。如果将数据库的库根据不同服务进行拆分,不同服务依赖不同的库,库与库之间的数据共享通过数据冗余来完成,这样会会引来更多问题,因此系统做拆分时,需要好好考虑这些问题,避免踩坑。

按模块拆还是按关联业务拆?

举一个电商后台系统的例子,一般来说一个电商系统核心有这么一些功能:

对于这些模块来说,有些人会按照模块分服务,这样的话不同的服务对应不同的模块,不同的开发人员维护不同的模块,这样听起来也不错,但是这样会遇到很多问题,仔细发现,不同模块之间存在依赖关系,比如店铺依赖商品,订单依赖风控,很多模块都依赖用户,这样的话,服务与服务之间的耦合便产生了。

因此,我们在拆分服务时,需要遵从根据关联业务拆分而不是根据模块去做拆分的原则,根据关联业务进行拆分可以避免服务之间的耦合,并且更容易扩展。如果依然存在耦合的业务,那么可以把耦合的业务抽出来做成单独的服务,这样服务可以保证单一职责的原则。

怎么控制拆分粒度?

在做微服务拆分时,控制拆分粒度也很重要。拆的太细,增加调度成本,拆的不细,容易造成耦合。因此,需要根据项目的情况对微服务做合理拆分。

举个例子,如果需要我们设计一个网上书店,主要有这么几个大体功能,各类图书的展示,商品交易,图书产销榜等各维度的榜单,用户个人数据展示等模块。对于这些功能,我们按照上面提到的按关联业务拆分成这么几个服务:

  • 订单处理服务 (处理订单请求)

  • 商城数据服务 (获取商品等信息)

  • 用户数据服务 (获取用户等信息)

如果我们按照这种拆分,对于中小用户规模没有多大问题,因为请求量不高的情况下对DB读写的负荷也并不是很大,所以多种不同的读业务放到同一个服务中并没有多大问题,但是如果像京东,当当书店这种规模的请求,我们就需要进一步的去拆分,商品,活动,推荐系统,搜索系统,CMS,社区,订单,后台管理系统等等做更细维度的拆分,这样能够保证系统的健壮性。

有状态和无状态分离

状态这个词在游戏开发中经常见到,因为游戏是强交互,服务端需要时刻保存玩家的entity,在互联网行业状态类似session,有一些业务可能需要多次请求服务端,服务端每次保存当前请求的状态供下一次请求使用,这种被称为状态,有状态的服务是不能直接多开的,因为下一次的请求如果被分配到其他服务上就会发生错误,因此需要通过一致性哈希等策略去保证请求都落在同一个节点上。

常见的有状态的业务场景有:

  1. 比如订单提交根据场景的不同可能涉及到状态,比如第一次向服务请求创建订单,第二次提交订单,这种场景服务端需要保留创建订单的状态(因为如果通过DB去保留状态开销会比较大),

  2. 比如实现一个计数功能,每次客户端请求服务都会计数,这种业务使得每次客户端都需要在同一台服务进行请求。

避免引入分布式事务问题

事务指的是要么成功,要么就失败,只要是用来避免脏数据。分布式事务指的是多台服务处理某个任务,要么全部处理成功,要么全部处理失败的情况。如果出现某些成功,某些失败的场景,就会出现数据不一致。引入分布式事务会给业务引来不必要的麻烦,比如有这么一个场景:

某数据服务需要给前端提供一些维度的数据展示,有些数据访问频率非常高,属于读多写少的场景,于是把该数据放到内存中去取。这样设计并没有什么问题,但是如果请求量增多,服务多节点部署,那么会带来一个问题,如果更新一个服务的内存,那么下次请求到其他服务,此时数据就不一致了。所以对于写请求就需要同步到每一个节点,但是一个节点的延迟过大都会影响所有节点。由此带来了分布式事务的问题,这样设计会对系统的性能造成影响。

因此,在设计的时候,尽量的去避免分布式事务问题,如果无法避免,也应该避免通过强一致的方式,可以采取最终一致的方式去弥补。

核心与非核心

服务拆分还有一个补充的就是将核心业务与边缘业务进行拆分,这样的一个好处是边缘业务线上出了问题也不会影响核心业务,比如有见过一些项目把订单交易系统和数据展示的接口放一起,调用一些数据展示的接口时,如果出了一些问题,比如读写冲突,空指针,数组越界等问题都会使服务挂掉,势必会影响核心的订单交易系统,如果此时有订单在写入,还会产生更严重的问题。

其次,一些数据展示的需求变动也比较大,而订单交易系统一般变动比较小,如果经常发布,那么会对此时正在交易的用户产生影响,因此,在做系统设计时,有必要考虑这些问题。

更多干货请关注公众号:黑客的成长秘籍

微服务系统设计(一) -- 如何拆分服务相关推荐

  1. 微服务系统设计——数据模型与系统架构设计

    摘要 经过前面需求梳理,商场停车收费业务需求情况已经十分明了,本节就依据前文的输出作为输入,开始系统设计工作,包括功能模块设计.存储设计.架构设计等,为后面编码提供良好基础保障. 一.数据实体设计 基 ...

  2. 微服务的战争:按什么维度拆分服务

    微服务,这三个字正在席卷着目前的互联网软件行业,尤其在近几年云原生迸发后,似乎人人都对微服务有了更广泛的使用和理解,张口就是各种各样的问号,有着强大的好奇心. 无独有偶,我有一个朋友鲤鱼在内部微服务的 ...

  3. 学习笔记:带你十天轻松完成 Go 微服务系列(二)- 服务拆分

    学习笔记:带你十天轻松搞定 Go 微服务系列(二) 1.学习课程 2.服务拆分 2.1 按业务服务拆分 2.2 按调用方式拆分 3.创建项目目录 3.1 在 code 中新建项目 3.2 创建 mal ...

  4. 基于Kubernetes、Docker的机器学习微服务系统设计——完整版

     内容提要 1 概述 2 系统介绍 2.1 功能全览 2.2 核心功能 3 系统架构 3.1 云化架构图 3.2 架构说明 4 云化部署 4.1 部署图 4.2 部署说明 4.3 部署实例 5 设计实 ...

  5. 云原生架构下微服务最佳实践-如何拆分微服务架构

    转自: https://mp.weixin.qq.com/s?__biz=MzI3MzEzMDI1OQ==&mid=2651821066&idx=1&sn=8475f813a8 ...

  6. Spring Cloud构建微服务架构(一)服务注册与发现

    Spring Cloud简介 Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁 ...

  7. 架构设计:分布式服务,库表拆分模式详解

    简介:分布式系统架构的明显特点,就是按照业务系统的功能,拆分成各种服务,每个服务下面都有自己独立的数据库,以此降低业务间的耦合度,隔离不同的数据库保证系统最大的稳定性等. 一.服务间隔离 1.分布式结 ...

  8. Spring Cloud构建微服务架构:服务容错保护(Hystrix服务降级)【Dalston版】

    前言 在微服务架构中,我们将系统拆分成了一个个的服务单元,各单元应用间通过服务注册与订阅的方式互相依赖.由于每个单元都在不同的进程中运行,依赖通过远程调用的方式执行,这样就有可能因为网络原因或是依赖服 ...

  9. Spring Cloud构建微服务架构:服务容错保护(Hystrix服务降级)【Dalston版】 1

    前言 在微服务架构中,我们将系统拆分成了一个个的服务单元,各单元应用间通过服务注册与订阅的方式互相依赖.由于每个单元都在不同的进程中运行,依赖通过远程调用的方式执行,这样就有可能因为网络原因或是依赖服 ...

最新文章

  1. 十折交叉验证10-fold cross validation, 数据集划分 训练集 验证集 测试集
  2. ElementUI项目中怎样引用Jquery
  3. Oracle数据库使用Analyze提升sql性能
  4. java自动转换_java类型转换详解(自动转换和强制转换)
  5. 牛客网 【每日一题】4月10日 二分图染色(弱化版)
  6. junit规则_JUnit规则
  7. optimizer_mode优化器模式
  8. 凯撒密码加密,解密的实现,可以在项目上使用
  9. Layui layui-soul-able 组件 表格列进行拖拽
  10. Python代码格式化规范
  11. ofstream 二进制 文本_C/C++读写文本文件、二进制文件的方法
  12. 天勤数据结构顺序表算法操作含完整测试
  13. 2015 年度新增开源软件排名 TOP100
  14. MATLAB中图像模式转换
  15. P3755 [CQOI2017]老C的任务
  16. 如何在Ubuntu 20.04上安装和使用TimescaleDB
  17. 硕士论文查重流程是什么?
  18. 【总结】Android的16ms和垂直同步以及三重缓存
  19. 概率论笔记1.5伯努利模型(二项分布)
  20. python中有数组吗_python中有数组吗

热门文章

  1. oracle maxidletime,ORA-02396:超过最大空闲时间,请再次连接
  2. 上汽董事长称不接受与华为合作自动驾驶;曝OPPO给离职员工补发年终奖,此前遭克扣;Google Play 将启用AAB格式应用...
  3. 软件工程实训有必要吗_软件工程实训心得体会
  4. Python3.6安装PyQt5的方法
  5. 报错:NoSuchAlgorithmException: Algorithm HmacSHA1 not available
  6. 【2012年中山纪念中学信息学竞赛初一选拔赛一】美丽的纪中(a)
  7. 1.有四个数字:1,2,3,4能组成多少个互不相同且无重复数字的三位数?各是多少?
  8. java氧气版,氧气呼吸器属于( )。
  9. 前端之jquery-jQuery中$(function(){})与(function($){})(jQuery)、$(document).ready(function(){})区别
  10. 无人机3d可视化系统的应用是怎样实现的?