专栏首页IT大咖说【大咖连载】SockShop系统服务划分与设计

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

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

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

9.1 系统综述

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

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

  • SockWorks公司的在线袜子商店系统SockShop是基于SpringMVC开发的单体应用,代码库庞大,变更困难。
  • SockWorks公司的软件开发的过程还是瀑布式,交付周期超过30天。
  • SockWorks公司的IT组织结构属于矩阵型,开发、测试、运维分属不同的部门,沟通成本高。
  • SockWorks公司的IT部门自建了相关的基础设施,但是运维自动化水平不高,运维人员大多数的时间都花费在解决生产环境问题上。

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

  • 当前的SockShop系统是否适应于微服务架构。
  • 如果适用,是选择对原有系统解耦还是重新实现。
  • 如果SockWorks的IT组织所处的阶段需要做哪些事情可以助力推行微服务。

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

图9-1 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的基础上进行改造的。

9.2 需求理解与分析

9.2.1 总体需求

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

功 能

详细描述

用户注册登录

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

浏览商品信息

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

购物车

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

购物车结算

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

订单支付

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

订单查询

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

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

9.2.2 其他非功能性需求

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

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

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

9.3 服务划分与设计

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

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

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

9.3.1 建立统一语言

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

图9-2 SockShop系统的统一语言

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

9.3.2 业务流程梳理

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

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

图9-3 用户购物流程

9.3.3 采用事件风暴进行领域建模

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

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

图9-4 领域事件

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

图9-5 命令模型

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

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

图9-6 识别聚合的结果

9.3.4 服务划分

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

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

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

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

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

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

  • 用户界面服务(Frontend Service)
  • 用户服务(Users Service)
  • 购物车服务(Carts Service)
  • 订单服务(Orders Service)
  • 商品列表服务(Catalogue Service)
  • 支付服务(Payment Service)
  • 物流服务(Shipping Service)

本文分享自微信公众号 - IT大咖说(itdakashuo)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-09-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Spring Cloud+云计算SaaS=?

    摘要 云帐房CTO张英磊基于自己的个人经验,分享Spring Cloud在云计算SaaS中的实战经验,希望能为大家带来一些思路上的帮助。 ? SaaS漫谈 Sa...

    IT大咖说
  • 【大咖连载】服务设计与实现

    服务设计会影响到业务需求是否被正确、高效地实现,良好的服务设计能够帮助领域专家与开发人员之间,以及团队内部进行高效、准确的沟通。良好的实现则能缩短服务上线的周期...

    IT大咖说
  • 经历了研发困局、运维之痛,同程微服务从1到1w的旅程

    内容来源:2017 年 9 月 9 日,前同程艺龙架构师谢康在“ArchData技术大会上海站”进行《同程微服务从1到1w的旅程》演讲分享。IT 大咖说(微信i...

    IT大咖说
  • Python中定义只能实例化一个对象的类

    >>> class Single(object): total = 0 def __init__(self): if Single.total > 0: ...

    Python小屋屋主
  • 外链建设:HTML链接写法

    如果你们熟悉HTML链接这节课可以忽略。但在我接触过的企业或者市场营销员工很多都不知道HTML链接写法。他们在做SEO的时候花了很多时间在学习HTML这是方向性...

    林雍岷
  • 通用Web后台魔方NewLife.Cube

    魔方 是一个基于 ASP.NET MVC 的 用户权限管理平台,可作为各种信息管理系统的基础框架。

    大石头
  • 程序员必知的LinuxShell命令

    程序员必知的LinuxShell命令 grep (Globle Regular Expression Print全局正则表达式) 命令是一种强大的文本搜索工具,...

    王小雷
  • 魔方 NewLife.Cube

    魔方 是一个基于 ASP.NET MVC 的 用户权限管理平台,可作为各种信息管理系统的基础框架。

    大石头
  • 关于Nginx,我犯了一个傻逼的错误

    一开始以为后端数据库查询的问题,毕竟关联了好几张表,把SQL拷贝出来执行了一下,然而也就几十毫秒而已,不死心又在后台打印了一下执行时间,一切正常。

    小柒2012
  • 解读等保2.0,缺不了灾备!

    将异地备份的频度提升为实时备份,且需要制定数据的备份策略和恢复策略、备份程序和恢复程序等。

    冬瓜哥

扫码关注云+社区

领取腾讯云代金券