按照业务能力的划分方式来设计一些服务来提供投资策略的功能。
为了让用例更加直观,我们用线框图画出了管理员创建投资策略的界面原型。
管理员创建投资策略的界面原型想要按照业务能力来设计服务的话,最好从一个领域模型开始。领域模型是对限界上下文中业务所要执行的功能以及所涉及的实体的描述。一个简单的投资策略包含两部分:名称和一组按百分比分配的资产。
SimpleBank公司的管理员负责创建策略,初步列出了这些实体。
这些实体的设计模型图会有助读者理解服务所要拥有和保存的数据。只有3个实体,另外,我们至少已经确定了两个新的服务:用户管理(user management)和资产信息(asset information)。用户(user)和资产(asset)实体分别属于截然不同的两个限界上下文。
(1)用户管理——包括诸如注册、认证和授权这样的功能。在银行环境中,出于安全、法规和隐私方面的原因,为不同的资源和功能授权是受到严格管制的。
(2)资产信息——包括与第三方市场数据提供方服务的集成,这些数据包括资产价格、类别、等级以及财务业绩等。另外,还包括界面原型上所要求的资产搜索功能。
有趣的是,这两个不同的领域同时反映了SimpleBank公司本身的组织结构。公司有一个专门的运营团队管理资产数据,也有专门的团队负责用户管理这方面的工作。这种相似性是值得的,因为这意味着我们的服务会如实反映现实世界中一系列的跨团队沟通。
再回到投资策略部分。我们可以将投资策略和客户账户关联起来,然后用它们来生成订单。账户和订单是两个截然不同的限界上下文,但是投资策略既不属于账户上下文,也不属于订单上下文。当策略发生变化时,这个变化并不会影响账户和订单它们自己的功能。反过来,将投资策略添加到账户或者订单中任何一个服务中都会阻碍相应服务的可替代性,降低服务的内聚性,增大修改的难度。
这些因素表明投资策略是一种独立的业务能力,我们需要一个新的服务。上下文与现有功能的关系如图所示。
该图中可注意到,上下文中的某些实体是共用的:它们在概念上是相同的,但是在不同的上下文中,它们与上下文的关系及其行为是各不相同的。比如,我们会以多种方式使用资产实体:策略上下文记录了不同策略的资产配置情况;订单上下文管理资产的买进和卖出;资产上下文存储诸如价格和分类这些基本的资产信息,供其他上下文使用。
该图中模型并不会告诉开发者服务的具体行为。它只会告诉开发者,这个服务包括的业务范围。现在已经对服务边界的设置有了更深入的了解,可以起草一份契约将服务提供给其他服务或者终端用户了。
首先,投资策略服务需要暴露创建和获取投资策略的方法。这样,其他服务或管理后台界面就可以访问这个数据了。
如果我们之后还要再次使用策略的话,就需要获取这些策略数据。
其次,还应该考虑一下这个服务应该发出什么事件消息。基于事件的模型有助于解除服务之间的耦合,这可以确保我们能编排耗时较长的服务交互,而不需要显式地编配出这些交互过程。
比如,假设策略创建成功后会触发系统向对该策略感兴趣的潜在用户发送一封邮件通知。这个功能与Investment strategy服务本身的功能范围是无关的;Investment strategy服务并不了解客户的信息以及他们的偏好。在这种场景下,事件是非常理想的方案,如果向/strategies发送POST请求,事后触发了一个StrategyCreated事件,那么任何微服务都可以监听这个事件并执行相应的操作。
太棒了!——我们已经确定了这个用例所有需要支持的功能。为了解这些功能是如何相互配合的,我们可以将investment strategy服务与其他在线框图中已经明确的功能进行关联。
总结一下目前所做的工作:针对示例问题,确定了业务创造价值所要完成的功能以及SimpleBank公司不同的业务领域范围之间固有的边界;借助这些知识,识别出属于不同能力的实体和职责,确定了微服务应用的边界;将系统划分到一个个能够反映这些业务领域边界的服务中。
通过这种方法设计出来的服务相对稳定、有内聚性、面向业务价值并且相互之间耦合度低。
每个限界上下文都会为其他上下文提供API,同时将内部操作封装起来。
(1)它为其他上下文暴露了一些方法,比如查询和获取资产信息。
(2)SimpleBank公司的专家团队或第三方集成方负责添加资产数据。
这种私有操作和对外接口分开的方案提供了为服务演化提供了一种非常有用的途径。在系统生命周期的前期,我们可以选择开发粒度粗一些的服务来体现高层次的边界。随着时间的推移,我们可能在未来需要将服务分解,将内部嵌套的上下文中的功能开放出来。这样就能够保持服务的可代替性以及高内聚性,即使业务逻辑的复杂度越来越高。
挑战点1.需要大量的业务知识
按照业务能力划分服务需要对业务或者问题领域有深入的了解。这是很困难的。如果信息了解不充分——或者做出了错误的假设的话——我们就无法百分之百确定所做的设计决策是否正确。不管是了解哪个领域的业务需求,这都是一个复杂、耗时、需要反复迭代的过程。
挑战点2. 粗粒度服务不断发展
按业务能力进行服务划分的方式倾向于在初期阶段开发粗粒度服务——比如order、account和asset这种业务边界覆盖较大的服务。新的需求会不断拓展对应业务领域的广度和深度,相应地,服务的职责范围也会越来越广。这些新的变更理由可能与单一职责的原则相冲突。为了保持服务的内聚性和可替换性处于合理的水平,就需要进一步拆分服务。
摘取自 摩根·布鲁斯和保罗·A.佩雷拉的《微服务实战》
网友评论