SockShop系统服务划分与设计 大咖连载一 (socks和gloves的o发音一样吗)

SockShop系统服务划分与设计 大咖连载一 (socks和gloves的o发音一样吗)

我们已经熟悉了 ServiceComb 以及 ServiceStage。从本章开始,我们将基于 Weaveworks 开源的 SockShop,虚构一个 SockWorks 公司服务化的案例。同时,在这个过程中,使用 ServiceComb 进行微服务的开发,并基于 ServiceStage 完成服务的部署和维护。

本章将聚焦 SockShop 系统的需求分析以及主要的设计。同时,也完成持续集成、预生产环境、生产环境的搭建。

系统综述

SockWorks 是一家专业从事袜子设计、生产与销售的传统公司,每年会有 1000 余款时尚经典花型的袜子不断更新并上市,产品远销海内外。公司在线下的袜子销售业务发展稳定,但是随着网上购物的普及和消费观念的转变,以及来自于竞争对手的压力,SockWorks 在线下的销售逐渐趋于饱和。公司的 CEO 决定利用现有的线上系统,快速推出新特性,吸引更多客户,并增加用户黏度,拓展业务。

然而在和 CTO 沟通后,CEO 发现存在一些问题:

这些问题导致现有的 SockShop 系统无法满足 CEO 的期望。SockWorks 的 CTO 认为,要实现 CEO 的想法,可能需要对系统架构进行改造。但是他们不确定以下几个问题:

于是,SockWorks 公司基于第二部分提到的适应性评估以及微服务参考模型,利用微服务在线评估系统快速进行了适应性评估和微服务成熟度评估,发现虽然 SockShop 系统适于微服务架构,但是 SockWorks 公司的 IT 组织在全功能团队、部署管理、运维管理、测试管理等维度都处于较早阶段。随后 ServiceStage 的顾问深入 SockWorks 公司,通过和团队中不同角色,架构师、开发人员、测试人员、产品经理的沟通,梳理清楚了产品的价值流映射图。SockWorks 原有产品的价值流映射图,如下图所示。

SockWorks 原有产品的价值流映射图

从价值流图中发现产品在开发、测试、部署阶段存在的问题。

并从中发现导致产品发布周期长的主要原因如下:

根据当前所处的状况,基于微服务实施参考模型,顾问为 SockWorks 制定了两个阶段的演进计划。

第一阶段主要包括:

第二阶段主要包括:

在本章中,笔者将基于这两个阶段的计划,分别实现 SockShop 系统的不同服务,并利用 ServiceStage 的运维能力实现自动化运维。主要内容包括:

接下来让我们看看如何实现全新的 SockShop 系统。

本书为了方便起见,在实战篇中使用了 ServiceComb 作为微服务开发框架,华为云的 ServiceStage 作为持续集成、部署、运行的平台。实际上,微服务的实现也可以使用其他框架(如 SpringBoot、Spring Cloud、Finagle、Nodejs、Golang 等),持续集成也不局限于任何工具(Jenkins 2.0、Travisci、ConcourseCI、Buildkite 等),读者可以基于具体的需求进行修改。

SockWorks 公司是笔者虚构的,是为了展示利用参考模型进行微服务演进的过程。SockShop 系统的实现是在 weaveworks 已有的 SockShop Demo 的基础上进行改造的。

总体需求

SockWorks 的产品经理认为 SockShop 系统需支持用户完成注册、登录,并支持商品的信息进行浏览、加入商品到购物车,以及结算、支付和订单查询的等功能。具体功能如下表所示。

(1)功 能

(2)详细描述

(3)用户注册登录

为了保证用户第二次回到 SockShop 能够找到自己的购物信息,系统需要提供用户注册与登录功能。在注册阶段,用户需要输入的个人信息包括用户名、密码和邮箱。在登录阶段,用户需要输入用户名和密码完成登录。

(4)浏览商品信息

为了让用户能够看到所有袜子的信息,以便挑选自己喜欢的袜子并完成进一步的购物,系统将提供袜子信息浏览功能,用户登录首页便能看到袜子的商品信息和款式,以及价格。

(5)购物车

为了让用户能够同时购买多双袜子,同时让用户在购买比较累时能够退出休息,回到 SockShop 继续完成购买,系统将为用户提供购物车功能。

(6)购物车结算

当用户想完成购物时,需要对购物车进行结算,此时会生成一个订单,以便用户进一步支付。

(7)订单支付

货到付款的功能会影响 SockWorks 公司的现金流,所以 SockShop 系统暂时只支持在线支付,需要提供订单支付功能。

订单查询系统同样会保存用户的历史订单,提供订单查询功能,以便用户需要时进行查询。

除了表中所列的基本功能之外,在系统首个版本上线后,根据线上销售业务的情况,公司会进一步考虑推出购物卡、丰富会员机制,并实现商铺加盟、在线交流等高级功能。

其他非功能性需求

在与产品经理进一步的沟通中了解到,由于袜子是快消品,普遍以薄利多销为主,这意味着订单数量巨大,用户访问量较高,尤其是在活动促销期,线上袜子商店需要应对比平时高出许多倍的流量,产品经理希望 SockShop 也能够应对这种突发情况。因此,为了能够给用户流畅的购物体验,系统的核心功能应该能够快速伸缩,避免资源不足和浪费。在公司业务发展、用户急剧增长的过程当中,需要通过可靠性措施来避免出现系统不堪重压而崩溃等问题。

同时,对于 SockShop 这种传统企业来说,希望能够降低运维成本,因此在系统上线之后,出现故障时需要能够让运维人员快速定位故障问题,解决故障,减少人力成本、减少系统故障带来的商业损失。同时在当系统发布新功能时也不能引起业务中断。为了能够让 SockShop 系统尽快上线提供销售服务,以应对来自竞争对手的压力,又能够满足将来公司的扩张诉求,从而减轻公司库存压力和运营成本,需要开发团队能够快速开发出核心功能交付上线运行。

以上便是 SockShop 系统的功能和非功能性需求,公司希望技术团队能够聚焦业务,降低开发成本,使系统快速上线,并能利用自动化的监控运维机制,应对瞬息万变的销售市场。

服务划分与设计

SockWorks 公司不仅希望新的 SockShop 系统能够快速稳定上线新特性,同时也希望在活动促销期间系统流量增加时系统能够伸缩,在系统不堪重负时核心功能依然能够提供服务。在第 1 章“微服务架构综述”中,笔者提出了创新软件的四个“S”,即 Speed、Safety、Scale、Sharing,这也正是 SockShop 系统所需要具备的。

通过微服务的适用性评估,团队一致认为该业务可以采取微服务架构实现。同时,IT 团队希望能发挥微服务架构的优势,采用异构技术来实现不同的服务,提高团队成员的技术储备与开发效率。

另外,有效拆分业务逻辑是微服务化架构设计的一个重点。SockWorks 的 IT 团队在设计新的 SockShop 系统时,采用了领域驱动设计的方式,对 SockShop 系统进行业务梳理以及划分。

建立统一语言建立统一语言是领域驱动设计的核心,它一方面帮助技术人员快速理解业务,另一方面保证设计的持续演进。在 SockShop 系统中,架构师、软件开发人员首先与领域专家沟通,了解到系统需要提供以下核心功能:用户注册、登录、浏览商品信息、购物车、下单、支付以及历史订单查询功能,通过对这些需求的梳理,提取出核心业务名词,作为该系统的统一语言,如下图所示。

SockShop 系统的统一语言

在后续的实现过程中,领域专家与开发人员、开发人员内部之间,将使用上述术语进行讨论,比如在 SockShop 系统中,提到“商品”就代表袜子。在开发人员的代码实现中,也会使用上述术语实现业务逻辑。

业务流程梳理通过领域专家与开发人员的沟通,团队在理解了业务的基础上,梳理出了用户的购物流程,如图所示。

首先用户在完成注册或登录后,可以进行历史订单查看或者浏览商品,如果对某商品感兴趣,可以查看商品的详细情况。将商品加入购物车后,用户可以继续浏览商品,也可以进入到购物车内查看并下单。在下单过程中,分别需要填写收货地址信息和支付信息,在确认订单后选择提交订单。当物流到达后,用户确认收货。

用户购物流程

采用事件风暴进行领域建模在梳理出业务流程后,SockWorks 的 IT 团队采用事件风暴进行领域建模。事件风暴(Event Storming)是由 Alberto Brandolini 提出的一项团队活动,旨在通过领域事件识别出聚合根,进而识别出限界的上下文,指导团队进行服务划分。关于事件风暴的更多内容,请读者参考《Introducing Event Storming》。

首先,团队根据业务流程识别出领域事件,并按照时间序列进行组织,其结果如下图所示。领域事件是领域驱动设计中的一个概念,以数据的形式来记录业务事件,用于捕获所建模的领域中所发生过的事情,通常用“已发生”时态来表达。

领域事件

接下来团队对产生事件的命令进行建模,输出的命令如下图所示。命令是触发领域事件的源头,它可以是用户通过界面进行的操作,可以由外部系统触发,也可以是定时任务。

命令模型

最后,团队基于命令与领域事件,识别聚合。聚合是领域驱动设计中的概念,它由一组相关的领域对象构成,目的是确保业务规则在领域对象的各个生命周期中都得以执行。聚合接收命令并产生领域事件,处于聚合内的对象,只能通过聚合根对其修改。

系统地梳理出用户、商品、购物车、物流、订单各个聚合,由于这几个聚合较为独立,可以分别形成用户子域、商品子域、购物车子域、物流子域以及订单子域,至此,系统的限界上下文整理完毕。识别聚合的结果,如下图所示。

识别聚合的结果

服务划分根据上面梳理出的限界上下文,将系统拆分为用户服务、商品服务、购物车服务、物流服务以及订单服务。

领域模型没有涵盖支付功能,针对这种情况,一种方式是将支付功能放在订单服务内部;另一种方式是将其作为独立的服务。

如果在业务梳理的过程中抽象出交易模型(Transaction),用于记录每次支付或退款过程,便可划分独立的交易服务或支付服务。此处由于简化了购物的处理流程,因此没有抽象出独立的支付服务。

对于物流相关逻辑,也可以抽象出独立的物流服务,对接第三方物流公司的接口,并与实际的物流解耦。对于上述的各个服务,需要一个用户界面服务将整个流程贯穿起来,负责用户的接入。通过定义用户界面服务,既可以用来接入用户请求,又可以起到聚合的作用。

此外,在用户界面服务后面需要一个认证授权服务,用来验证对后台服务的请求是否合法,即用户是否是已登录的合法用户。由于后台服务都是无状态的,用户的登录信息包含在请求所携带的 Token 中,因此认证授权功能主要通过对 Token 的校验来完成,认证授权服务将主要负责用户登录注册后 Token 的生成与校验。如果把用户界面服务本身看作一个网关,那么认证授权功能也可以位于用户界面服务中。

本书中主要为了演示基于 ServiceComb 的业务功实现,因此并未考虑复杂的认证授权功能。最终,SockShop 系统将包含以下服务:

声明:本文来自用户分享和网络收集,仅供学习与参考,测试请备份。