微服务系统设计(一) -- 如何拆分服务

本文探讨了微服务设计中的关键问题,包括何时拆分服务,如何避免过早优化,以及服务拆分的原则。强调了单一职责、业务粒度、避免互相依赖、状态与无状态分离和分布式事务的管理。建议根据关联业务而非模块拆分服务,并控制拆分粒度以适应不同规模的用户需求。同时,指出核心业务与边缘业务的拆分能提高系统的稳定性和容错性。
摘要由CSDN通过智能技术生成

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

前提

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

怎么拆分服务

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

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

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

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

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

举一个电商后台系统的例子,一般来说一个电商系统核心有这么一些功能:
在这里插入图片描述
对于这些模块来说,有些人会按照模块分服务,这样的话不同的服务对应不同的模块,不同的开发人员维护不同的模块,这样听起来也不错,但是这样会遇到很多问题,仔细发现,不同模块之间存在依赖关系,比如店铺依赖商品,订单依赖风控,很多模块都依赖用户,这样的话,服务与服务之间的耦合便产生了。

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

怎么控制拆分粒度?

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

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

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

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

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

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

有状态和无状态分离

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

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

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

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

避免引入分布式事务问题

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

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

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

核心与非核心

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

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

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

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值