写点什么

【大咖连载一】SockShop 系统服务划分与设计

王磊 马文博 张琦

  • 2019-09-04
  • 本文字数:5081 字

    阅读完需:约 17 分钟

【大咖连载一】SockShop系统服务划分与设计

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


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

系统综述

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


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


  • SockWorks 公司的在线袜子商店系统 SockShop 是基于 SpringMVC 开发的单体应用,代码库庞大,变更困难。

  • SockWorks 公司的软件开发的过程还是瀑布式,交付周期超过 30 天。

  • SockWorks 公司的 IT 组织结构属于矩阵型,开发、测试、运维分属不同的部门,沟通成本高。

  • SockWorks 公司的 IT 部门自建了相关的基础设施,但是运维自动化水平不高,运维人员大多数的时间都花费在解决生产环境问题上。


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


  • 当前的 SockShop 系统是否适应于微服务架构。

  • 如果适用,是选择对原有系统解耦还是重新实现。

  • 如果 SockWorks 的 IT 组织所处的阶段需要做哪些事情可以助力推行微服务。


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



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


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


  • 开发:从需求规划到开发完成周期为 13 天。造成这一问题的原因是应用代码量庞大,模块间耦合大,需求的分解粒度比较粗,每个 Story 的工作量有 800 行以上的代码。同时,受开发流程制约,需要统一 Story 的开发计划。

  • 测试:测试周期为 8 天。矩阵型组织结构导致开发团队和测试团队分离,反馈周期长。自动化测试覆盖率不足 10%,只有少量单元测试、组件测试,无集成化测试,端到端测试以手工为主。

  • 部署:部署周期长达 13.5 天。原因包括开发人员和运维人员分属不同团队,版本发布整体规划、部署的区域较多,过程为手动。


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


  • 产品主体为单体应用、代码庞大、服务耦合性要求严重、技术落后、拆分成本太高、变更困难。

  • 交付过程缺乏自动化测试、部署,没有建立交付流水线,效率低。


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


第一阶段主要包括:


  • 应用微服务架构,通过领域驱动设计的方式,重新设计整个 SockShop 系统。

  • 采用 ServiceComb 微服务开发框架实现第一个 SockShop 系统的微服务。

  • 在实现第一个微服务时,尝试自动化测试、持续交付部署等,提升团队在这些维度的能力。

  • 将微服务部署在 ServiceStage 集群中,实现自动化的部署。


第二阶段主要包括:


  • 复制第一个阶段的实践,采用相同方式实现 SockShop 系统剩余的微服务。

  • 在 ServiceStage 集群上实现对整个 SockShop 系统的编排。

  • 利用 ServiceStage 的服务治理、监控、运维能力对 SockShop 系统进行高效运维。


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


  • 以持续交付的方式,使用 Java Chassis 实现 SockShop 系统的第一个服务。

  • 使用 Go Chassis、Nodejs 实现其他服务,并通过 Mesher 来接入 Nodejs 应用。编排部署和运维 SockShop 系统。


接下来让我们看看如何实现全新的 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 系统将包含以下服务:


  • 用户界面服务(Frontend Service)

  • 用户服务(Users Service)

  • 购物车服务(Carts Service)

  • 订单服务(Orders Service)

  • 商品列表服务(Catalogue Service)

  • 支付服务(Payment Service)

  • 物流服务(Shipping Service)


2019-09-04 17:374567

评论

发布
暂无评论
发现更多内容

区分重载和重写,轻松掌握 Java 多态

飞天小牛肉

Java 程序员 面试 后端 2月春节不断更

LeetCode题解:297. 二叉树的序列化与反序列化,DFS,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

正确面对倦怠感,提升职场战斗力

boshi

职场成长 七日更

5G点亮工业革命前,2021需要持续点亮5G

脑极体

产品经理训练营第四次作业

Jobs

业务流程与产品文档

王一凡

产品经理训练营

数据结构与算法 - 排序1.冒泡排序

小马哥

Java 排序算法 数据结构与算法

HTTPS的安全性从何而来?

金融科技的碎片化思考(中)

曲水流觞TechRill

金融科技

【STM32】0.96寸OLED显示屏(7针SPI协议)软件模拟SPI

AXYZdong

硬件 stm32 2月春节不断更

话题讨论 | 你是不是一个特别容易被说服的人?

石云升

话题讨论 2月春节不断更

你真的了解 sync.Mutex吗

Leo叔叔

mutex Go Concurrency Patterns Go 语言

Elasticsearch 精确匹配与全文搜索

escray

elastic 七日更 死磕Elasticsearch 60天通过Elastic认证考试 2月春节不断更

话题讨论 | 如何获得令人心动的前端offer

我是哪吒

程序员 面试 大前端 话题讨论 二月春节不断更

【得物技术】走进Web3D的世界(1) 画个立方体吧

得物技术

html html5 js WebGL 得物技术

第4周作业_贷款申请用例

园子

互联网金融 小额贷款 去中心化金融借贷系统开发

你看那个程序员,每年升职加薪,日赚3千

谙忆

产品训练营 - 第四周 - 作业

邹小胖

产品训练营

深入了解gradle和maven的区别

程序那些事

maven Gradle 程序那些事 构建工具

Java容器--2021面试题系列教程(附答案解析)--大白话解读--JavaPub版本

JavaPub

Java 面试 hashmap javapub

马斯克说狗币牛逼,我说idea插件助你盯盘摸鱼

滑板上的老砒霜

比特币 idea插件 Android开发

20210209—生活记录

VC

二月春节不断更

极客时间购买课程用例

Geek_a32093

/(ㄒoㄒ)/~~晚了

Nydia

流媒体传输协议之 RTP(下篇)

阿里云视频云

音视频 流媒体 rtp

认识 Java 中的队列:Vector、ArrayList、CopyOnWriteArrayList、SynchronizedList

看山

Java 线程安全

从“乌鸡”到5G,不仅仅是谐音梗

脑极体

5. Python 循环的本质就是一段代码懒得重复写

梦想橡皮擦

Python Python Monad 2月春节不断更 python入门

用例文档练习

王一凡

产品经理

盘点和程序员相关的那些事,让你不再被割韭菜,薅羊毛!

孙叫兽

程序员 程序人生 高薪 话题讨论

产品经理 - 第三周作业

LLL777

【大咖连载一】SockShop系统服务划分与设计_开源_InfoQ精选文章