微服务的架构设计
首先,当我们将一个复杂的系统的各种业务仔细清点到台面上以后,得到的列表往往会比许多人最初想象得长得多,它能提醒我们系统的复杂度是否已经过高了。其次,列举业务的过程也是开发者与业务人员沟通的过程,来自不同业务线的代表也许会为某部分业务的价值点发生争执,或是提供一些许多开发人员此前并不了解的细节信息,将这些问题当面讨论清楚并非什么坏事。此外,当我们真的去仔细思考一个业务系统的核心价值时,也许会得出使人意想不到的结果。
继续举例子,在汽车的销售和售后平台中,通过业务建模,可以划分出许多子领域:
• 在线购车(渠道A)
• 在线购车(渠道B)
• 在线购车(渠道C)
• 试驾预约
• 售后服务
• 用户反馈
• 订单系统
• 促销活动
• 车辆市价信息
• 车辆参数信息
• 4s店信息
• 用户信息管理
• …
说明:这里渠道指的是销售平台对接的一个第三方系统,其中每个渠道可以对应多个汽车品牌
然后我们要从中识别出业务中的核心域。必须强调,服务领域划分仅仅是代表服务对系统关键业务贡献的价值,处于核心域中的那些服务应该是该系统业务成功的主要促成因素,从战略层面讲,企业应该在自己的核心领域上具有一定壁垒优势。经过讨论,开发者和业务人员最终得出让人大跌眼镜的结论,核心域部分的服务只有“试驾预约”和“售后服务”,因为这两项才是该企业最具竞争力的业务。而看起来十分重要的“在线购车”服务,由于并不具有特别的行业竞争优势而被划到了支撑子域中。正确的服务划分定位将对系统未来的发展策略产生积极的影响。
在这个系统中的“车辆市价信息”、“车辆参数信息”、“4s店信息”等服务都被划归到了通用子域。在通用子域中的服务并非最没有价值或是复杂度最低,而只是说明系统在这些服务领域中通常不具优势,因此这部分功能完全可以考虑外包开发或者购买第三方的现成服务。
使用符合业务结构的API
前面介绍业务建模的时候我们强调了使用“API集成”的必要性,以及它的反面形式“数据库集成”所带来的问题。在微服务的架构中,服务的技术选型可能是异构的,API的实现也会各有不同。除了Web应用比较流行的RESTful标准,还有像SOAP、ProtolBuf、MessageQueue等不同的协议与格式标准,它们都可以被作为服务之间通信的API。不同的API设计对服务使用的体验差别会很大,除去技术原因对API协议的倾向性,在设计和评价API方面依然有许多值得注意的地方。
一个好的API设计应该在接口的元数据中向用户提供尽可能多的有意义的业务信息,这里指的元数据包括例如API的名称、参数、标签等等用户在不需要专门查看文档就可以看到的内容。通常在各种不同的API协议里,总会存在一个相似的概念,就是目标路径。比如RESTful的URL地址,ProtolBuf的消息类型嵌套结构,MessageQueue名称里用斜线划分Topic路径的惯例等。以RESTful标准为例,可以试比较下面两种URL地址的差异。
• 第一种:/users/123/orders/123
• 第二种:/orders?id=123&user_id=123
显然前一种地址包含的信息更多,它告诉了访问者订单(orders)是属于用户(users)这个实体中的一个子实体,并且包含了一个潜在业务规则,即如果ID为123的这个用户不存在了,那么查询他下面的所有订单信息也是不具有业务意义的。实体之间的嵌套关系可以通过领域建模过程中的聚合识别。当然,这种URL结构有时会导致很长的API路径,但相比它所带来的业务语义,我们认为还是值得的。
类似的语义化例子还有例如:
• PUT /services/questions/123
• PUT /services/questions/123/comments/123
这是售后服务部分的两个API,分别用来更新提问的内容和提问的评论内容,它们也是按层级组织的。
有些通信协议中还提供了其他可以表明业务语义的元素。比如RESTful中使用GET/POST/PUT操作语义(查询/创建/修改),以及HTTP返回值中的语义信息等。在实际设计API时充分利用这些协议特性,能够使服务变得更加易用。
【微服务的架构设计】相关文章: