一、背景
传统的Web项目都是采用单体架构的方式来进行开发、部署、运维的,所谓单体架构就是将程序的所有业务模块全部打包在一个文件中进行部署。但是随着互联网的发展、用户数量的激增、业务的规模极速扩张,业务的复杂度急剧增加,传统的单体应用方式的缺点就逐渐显现出来了,给开发、部署、运维都带来了极大的难度,工作量会越来越大,难度越来越高。传统单体架构主要存在以下的问题:
- 随着业务复杂性的增加,开发变得困难,增加了研发成本抑制了研发效率的提升。
- 系统的运维成本很高,对某个功能的修改,都需要对整个系统进行构建、测试、部署。
- 技术栈单一,不能够很好地解决业务的多样化需求。
- 隔离性差,一个模块出现问题,可能导致整个系统崩溃。
- 可伸缩性差,对于部分业务的高并发,不能按需扩展。
为了解决上述问题,微服务架构应运而生。简单来说,微服务就是将一个单体应用拆分成若干个小型的服务,协同完成系统功能的一种架构模式,在系统架构层面进行解耦合,将一个复杂问题拆分成若干个简单问题。下面是采用微服务架构带来的优势。微服务带来的优势:
- 服务承载的业务逻辑内聚,易于开发与维护。
- 单个服务启动快。
- 技术栈灵活,独立的服务可以选用不同的技术栈。
- 独立的按需扩展,满足高并发与大流量。
任何一种架构方式都有自己的优势,同时也存在一定的不足,那么微服务带来的问题有哪些呢?
- 随着服务的增多,管理难度成倍加大。
- 服务间通信成本,包括网络延迟,接口不可用等,保证服务的高可用是一个核心难题。
- 系统集成测试涉及的服务较多,难度较大,不利于测试。
- 性能监控,原本只需要一个监控的部分,现在需要分开监控,如何快速定位问题是一个挑战。
- 重复建设,对于业务线拆分的组织架构,由于信息不对称导致重复性工作。
- 非中心化带来的数据不一致性。
- 业务解耦带来的微服务拆分困难。
总体来说,根据业务的复杂性,微服务架构与单体架构对生产率之间的关系如下图所示:
综上所述,随着公司业务的规模扩张,复杂性增加,公司内部的微服务数量也急剧地增多,对服务的管理、系统的集成测试、运维部署、系统监控及问题的定位排查都带来一定的挑战。如何进行微服务的拆分就是一个很关键的因素,合适的拆分将为企业带来效率的提高的同时,也带来了成本的降低。下面我们主要探讨下微服务如何拆分?
微服务拆分方式没有明确的标准,每个公司、每个团队、每个人对服务拆分的理解程度和拆分尺度都可能不一样。虽然没有直接的标准来指导微服务的拆分,但是如服务拆分的过细的话,会导致服务数量呈爆炸式增长,以至每开发一个业务功能,都需要和多个服务提供者的开发区沟通,这不仅增加了开发的复杂度,而且增加了测试运维的复杂度,降低了效率。但是,如果拆分的太粗,则又会因为服务提供的接口频繁变更,致使一次需求迭代影响众多服务,故障范围扩大,类似于单体架构,没有享受到采用微服务架构带来的好处。虽然微服务架构没有明确的标准,但是根据微服务的特性,并结合头部互联网公司和我们公司的实践,我们整理了一套微服务的拆分最佳实践。
首先,我们从微服务拆分的原则和拆分维度来讲解下整体的微服务拆分逻辑;其次,我们结合公司语音业务,详细介绍下语音业务团队微服务拆分前状,现阶段拆分;最后,我们基于第一部分的原则与维度,结合语音业务的现状,从上帝视角对现阶段的语音业务进行拆分。
二、微服务拆分最佳实践理论
2.1 拆分原则
单一职责
单个服务内部功能高内聚服务间低耦合。
闭包原则
- 微服务的闭包原则就是当我们需要改变一个微服务的时候,所有依赖都在这个微服务的组件内,不需要修改其他微服务。
服务自治
- 避免对其他微服务的强依赖。
- 避免环形依赖与双向依赖。
- 环形依赖和双向依赖说明微服务划分不合理,业务边界不清晰或者通用功能未沉淀。
持续演进
- 先粗粒度拆分,逐步演进,避免服务数量的爆炸性增长。
- 阶段性合并,随着对业务领域理解的逐渐深入或者业务本身逻辑发生了比较大的变化,亦或者之前的拆分没有考虑的很清楚,导致拆分后的服务边界变得越来越混乱,这时就要重新梳理领域边界,不断纠正拆分的合理性。
三个火枪手(服务拆分粒度原则)
- 服务拆分要考虑团队规模和业务复杂度,避免拆分过细带来较高的维护成本。
- 业务发展期,需要大量设计和开发工作,3人负责一个微服务,业务和技术上可互相讨论,互相备份,避免人员单点。
- 业务成熟期,主要以维护为主,开发工作较少,2人负责一个微服务,相互备份,避免人员单点。
- 每个人维护多个微服务,每个微服务被多个人维护相互备份,避免人员单点。
2.2 拆分维度
微服务的拆分可以从业务、技术和组织结构三个维度进行考虑。
2.2.1 业务维度
从一个公司的业务成熟度、业务所处的阶段和现阶段技术架构,基本可以考虑从两个方面进行业务领域分析、建模。分别是自顶向下和自底向上:
自顶向下 如果团队中有对一个业务领域非常熟悉的领域专家,这个时候由于领域专家对业务的全貌有比较清晰的理解,子领域边界清晰,再实践中经过验证,且此时公司整体技术需要进行重构,此时可按照领域驱动设计进行,由领域专家和技术专家在一起进行领域的抽象划分。比如电商领域,可以根据领域经验直接划分为,商品域、采购域、营销域、商户域、交易域、售后域、用户域、仓储配送域等等。
自底向下 初期以单体架构优先,因为面对一个新的领域,对业务的理解很难在开始阶段就比较清晰,往往是经过一段时间之后,才能逐步稳定,如果拆分过早,导致边界拆分不合理或者拆的过细,反而会影响生产力。很多时候,从一个已有的单体架构中逐步划分服务,要比一开始就构建微服务简单得多。同时公司的产品并没有被市场验证过,有可能会失败,所以这个投入的风险也会比较高。可以根据微服务拆分原则中的持续演进原则,先进行粗粒度的拆分,而后阶段性合并整合。
上述自顶向下还是自底向上进行业务分析,都需要采用DDD(领域驱动设计)的相关理论和方法,详细资料可以参考DDD网上其他资料。
2.2.2 技术维度
性能
- 将性能要求高或者性能压力大的模块拆分出来,避免性能压力大的服务影响其它服务。
例如电商的抢购,性能压力最大的是入口的排队功能;同时我们也可以基于读写分离来拆分,比如电商的商品信息,在 App 端主要是商详有大量的读取操作,但是写入端商家中心访问量确很少。因此可以对流量较大或较为核心的服务做读写分离,拆分为两个服务发布,一个负责读,另外一个负责写可以将排队功能独立为一个服务。稳定性
- 将成熟的和改动不大的服务拆分为稳定服务,避免被频繁的发布影响,稳定服务的拆分粒度可以粗一些。
- 将改动较多和业务迭代的服务拆分为变动服务,支持业务迭代扩展。
在实施微服务架构过程中,应该尽可能的缩短产品迭代交付周期,把需要频繁变更的功能尽量做成独立的服务,这样才能保证产品的新版本快速迭代、上线。可靠性
- 将可靠性要求高的核心链路拆分为核心服务,提供更多的资源,合理的降级策略,以及与非核心链路的隔离,游戏保证核心服务的高可用。
- 将可靠性要求低的边缘链路拆分为边缘服务,可适当降低可用性。
比如针对商家服务,可以拆分一个核心服务一个非核心服务,核心服务供交易服务访问,非核心提供给商家中心访问。
安全性
- 不同的服务可能对信息安全有不同的要求,基于安全隔离进行拆分。
例如面向用户的服务需要进行登录校验,面向内部的接口可直接访问;再比如设置特定的 DMZ 区域对服务进行分区部署,可以更有针对性地满足信息安全的要求,也可以降低对防火墙等安全设备吞吐量、并发性等方面的要求,降低成本,提高效率。通用性
- 将重复功能进行沉淀,独立为通用基础服务,减少重复开发。
不同的业务里或服务里经常会出现重复的功能,比如每个服务都有鉴权、限流、安全及日志监控等功能,可以将这些通过的功能拆分出来形成独立的服务,也就是微服务里面的 API 网关。防腐性
- 将第三方依赖、技术依赖抽象为防腐层服务,避免升级带来的业务功能影响。
异构性
- 对于对开发语言种类有要求的业务场景,可以用不同的语言将其功能独立出来实现一个独立服务。
2.2.3 组织结构维度
微服务拆分需要结合公司的具体组织结构,如果公司采用的是事业部的组织形式,微服务的拆分可能是按照康威定律。
康威定律
设计系统的组织,其产生的设计等同于组织之内、组织之间的沟通结构,通俗的说法就是:组织形式等同系统设计 从组织的维度我们可以认为微服务的本质是:“将一个个业务功能拆分出来,并由一个微型团队来开发、构建、运维,团队与团队之间通过定义清晰的边界进行沟通”。
下面一个例子能说明这个情况:你们团队目前负责A款APP的服务,现在由于公司业务变更,组织结构调整,需要将B款APP交由你们团队负责,由于之前A\B两款APP由不同的团队负责,各个团队都有可能有自己的针对首页的配置服务,当将B款APP交由你们团队后,你们团队针对首页的配置页面需要维护两套,你们团队的架构师从总体上看,两款APP使用两个配置服务,两个配置服务的大部分功能一致,只有部分功能是特异性的,因为团队合并,考虑到团队的效能,大局出发,一个团队不需要两个相似的配置服务,架构师可能需要对A款APP的配置服务进行抽象增强,是新的配置服务同时满足A和B的功能要求。此时,康威定律就发挥了至关重要的作用:“如果系统的架构和组织结构不一致,那么组织结构将成为赢家”。随着业务规模的继续增大,A和B两款APP都进入了高速发展,此时你们团队维护两个APP明显感觉吃力,此时需要进行业务拆分,你们团队继续负责A款APP, 由于A款APP对配置服务的使用程度较深,在进行服务划分时,配置服务划分给你们团队了,由于之前是大团队内部沟通,现在变为跨团队沟通了,所以B款APP团队决定另起炉灶,重新搭建配置服务。这里面其实还是康威定律发挥作用:组织内部的沟通路径(无论是否和正式汇报线一致)严重制约了组织所能设计的解决方案的类型。
逆康威定律
组织要根据他们想得到的软件架构来设计团队结构,而不是期望团队盲从一个被设计好的团队结构。过去很多组织结构调整的潜在目标都是为了减少员工或者围绕管理者和领导者的权势建立山头。可对于一家软件公司,势必慎重,必须要考虑架构,更可以应用逆康威定律:设计团队结构满足理想的软件架构。简而言之,在设计软件架构或进行组织结构调整时,将康威定律和逆康威定律纳入考虑因素之中,就能够受益于兼顾软件架构和团队设计的同态力。
三、聊天室微服务拆分演进
3.1 语音房背景介绍
业务特点:
- 业务涉及面广(个人房、官方房、打赏、订单等)。
- 社交推广+ 稳定营收。
- 大客户技术特点。
- 技术栈复杂(web server + im +音视频)。
- 强实时性(房间内)。
- 高并发(单房间流量)。
3.2 架构演进(业务支撑+稳定性)
3.2.1 单体架构1.0
此阶段面临的问题:
- 模块职责不清晰,依赖混乱。
- 无法有效支撑高并发、大流量场景。
3.2.2、单体架构2.0
演进思想 诉求:解决面临的问题并高效、快速的上线。
- 模块优化:单一模块重构优化。
- 服务分层:单体应用内各个模块解耦,单一职责,功能模块化,避免反向依赖循环依赖等问题。为下一步服务拆分打好基础。
- 服务支持弹性:应对大流量场景,服务支持水平扩展。
- 无状态应用容器化,水平扩展应对大流量场景。
- 核心DB资源可支持扩容,polarDB、redis集群版。
成果展示
3.2.3、微服务架构1.0
面临问题
产品形态趋于成熟,业务模块自治成为困难点 多人开发难维护、频繁发布导致稳定性降低等单体应用共通问题。
- 房间、增值、工会等独立业务线功能模块耦合严重。
- 无法对链路治理、服务稳定性无法得到保障。
- 业务对个人房单独运营的规划。
- 中台系统孵化拆分。
拆分目标
- 业务隔离。
- 通用性:将重复功能沉淀、独立为通用基础服务减少重复开发。
拆分逻辑
基于业务场景将聊天室拆分为聊天室营收服务、官方模板玩法及个人房三块系统,且个人房web网关独立,新增聊天室基建服务。
成果展示
功能架构图:
系统架构图:
3.2.4、微服务架构2.0(可靠性、稳定性)
面临问题 核心与非核心应用及功能耦合,无法进行精细化治理及监控。拆分目标
- 精细化链路服务治理。
- 核心与非核心应用隔离。
- 资源隔离。
拆分思路
- 可靠性:理出核心链路迁移至独立应用下,核心功能模块独立应用部署。
- 稳定性:成熟服务单独拆出。
成果展示
3.3 演进过程总结
单体服务治理
- 模块化
- 服务分层
- 应用弹性
单体拆分微服务1.0
- 通用性
- 稳定性:业务稳定性
单体拆分微服务2.0
- 稳定性:成熟服务剥离、减少频发发布。核心链路治理。
- 可靠性:核心链路非核心链路隔离。
- 性能:读写分离方向。
四、上帝视角下聊天室服务拆分
4.1、聊天室业务梳理
目前聊天室业务主要包含以下方面,如下图所示:
4.1.1自顶向下(领域专家描述)
业务层
- 个人房/官方房承载了房间的丰富玩法,用户可以在房间中娱乐互动、交友聊天,类似于在聊天室的基础上定义的具有特定功能的房间。
- 开黑房间、连睡、房间派对等业务是在聊天室中中承载的一种业务领域玩法。
- 飞鱼、尊享房间、FM节目单、包厅、守护是在聊天室中承载的一种独有的业务领域玩法。
- 聊天室小游戏是在聊天室承载的一种小游戏形态,小游戏本身由3方提供或者自建,除了能够在聊天室中承载,也能够在直播间承载。其核心依赖用户领域、游戏撮合领域、具体的游戏领域等。
- 聊天室打赏业务是公司所有打赏业务的一个具体的形态,这种打赏业务还包括直播间打赏、IM打赏、动态打赏等业务,打赏业务依赖用户领域、资产领域、礼物管理领域、支付业务领域、结算业务领域。
- 派单业务是在聊天室里面承载的订单业务的一个具体形态,由用户提出需求、主持人选择大神或者达人进行派单,达人抢单等流程,其核心依赖用户领域、资产领域、派单撮合领域、订单交易领域、支付领域、结算领域、优惠券领域。
- 守护团、守护勋章、贵族、挂礼物、用户礼包、红包、cp、宝箱等都是聊天室中承载的独有的业务营收领域玩法、涉及用户领域、资产领域、交易领域、支付领域、结算领域。
聊天室基础能力
- 公司核心业务包括,语音室,直播,->业务形态上的核心抽象是提供一个线上的场所供用户进行社交,核心基础能力是基础社交能力,包括图文聊天、语音、视频,商业模式是通过场所内的通过打赏提成、虚拟商品出售、系统撮合收费。
- 聊天室所有上层业务领域是由聊天室来承载,依赖聊天室领域的核心能力,同时直播间的所有业务领域是由直播间来承载,依赖于直播间这个基础能力。
- 聊天室领域包含的核心功能是:聊天室管理操作(座位、上下麦、权限)、聊天室自定义消息管理、聊天室基本信息维护、聊天室模板。
- 聊天室业务依赖房间业务,房间是更抽象更基础的核心功能:包括房间的创建、房间的管理。
- 聊天室业务依赖房间IM业务,房间IM业务承接了公司所有房间业务范畴的消息统一出口。
4.2、非功能型需求
房间、聊天室、直播房间应该具备高并发、低延时、稳定性高、可靠性强、可用性高等特点;聊天室打赏、红包、派单营收、用户礼包、宝箱等营收业务功能应具备高稳定性、高可靠性,且具备高可用性。
性能要求
- 高并发、高性能、低延时。
稳定性要求
- 核心能力的稳定性-从业务角度讲,房间基础能力需要具有稳定性,不能卡顿、延迟、掉线、无响应,变更需求不大。
- 交易能力的稳定性-交易直接影响公司经营状况,不能因为交易系统不稳定导致公司产生资损。
可靠性要求
- 核心能力的可靠性-从业务角度讲,房间基建需要,不能服务不可用。
- 交易能力的可靠性-交易直接影响公司经营状况,不能因为交易系统不可靠导致公司产生资损。聊天室打赏业务是公司核心营收业务,其业务的可靠性与稳定性直接影响公司业务。
4.3、服务拆分分析
4.3.1 业务领域-业务领域决定基本服务划分
使用原则:
- 持续演进。
- 三个火枪手。
- 业务领域决定基本服务划分 。
备注:拆分后服务承载,图中黑色方框标识 聊天室业务服务、用户服务、订单交易服务、礼物服务、榜单服务、游戏撮合服务、聊天室服务。
4.3.2 技术维度-技术影响的服务划分
关于通用性要求对于微服务划分的影响
- 将重复功能进行沉淀,独立为通用基础服务,减少重复开发。
- 聊天室服务拆分为:聊天室服务、房间服务、房间IM服务 房间服务和房间IM服务为通用服务,提供给除聊天室外公司所有类似场景使用。
- 订单交易服务拆分为:派单服务、交易服务、支付服务、结算服务、商品服务、营销服务、优惠券服务。
- 用户服务拆分为:用户服务、用户资产服务。
- 聊天室打赏业务从聊天室业务中独立出来形成聊天是打赏服务。
- 小游戏业务从聊天室业务独立出来形成通用的游戏服务。
关于性能要求对于微服务划分的影响
- 将性能要求高或者性能压力大的模块拆分出来,避免性能压力大的服务影响其它服务。
-
聊天室业务服务中的FM节目域、小游戏域涉及到持续的音频流,对性能要求较高,可以考虑独立拆分出来。
-
聊天室业务服务中飞鱼、尊享房间、包厅、FM节目是公共的官方聊天室中承载的业务,这个聊天室中业务流量大,性能要求较高,而开黑房间、连睡、房间派等是私人建立的房间,流量相对来说较小,性能要求低于前面的官方房间,故可以将这两类型业务拆开,如下所示 :
关于稳定性要求对于微服务划分的影响
- 将成熟的和改动不大的服务拆分为稳定服务,避免被频繁的发布影响,稳定服务的拆分粒度可以粗一些。
- 将改动较多和业务迭代的服务拆分为变动服务,支持业务迭代扩展。
- 聊天室服务、房间IM服务、房间服务涉及到核心能力的基础服务成熟且稳定,没有过多的业务需求。
- 订单交易服务、支付服务、礼物服务、榜单服务、打赏服务这些公共服务。
关于可靠性要求对于微服务划分的影响
- 将可靠性要求高的核心链路拆分为核心服务,提供更多的资源,合理的降级策略,以及与非核心链路的隔离,游戏保证核心服务的高可用。
- 将可靠性要求低的边缘链路拆分为边缘服务,可适当降低可用性。
聊天室业务服务中守护团域、守护勋章、表情、宝箱、cp、贵族、红包、挂礼物、用户礼包涉及到公司营收,可将他们划分为一个单独的服务 。
4.3.3 组织结构影响的微服务划分
4.4 最终服务拆分
通过上述对聊天室业务的自顶向下领域分析和业务的非功能性需求分析,基于微服务拆分原则,从业务、技术、组织维度进行微服务进行拆分,最总得出以下微服务拆分后的服务总体视图。
--- END ---
招聘信息
比心正在搜索优质人才的你,无论你是技术、产品、运营还是设计,只要你有一颗真挚的心,就赶快加入我们吧!投递邮箱:zhaopin@bixin.cn(邮箱主题请注明:比心-岗位-姓名)。