• 架构层级的“开闭原则”1


    在类的层级,开闭原则(the-Open-Closed-Principle,简称OCP原则)的含义是:一个类对扩展是“开”放的,而对变更是封“闭”的,意思是说,应该在不改变类的前提下扩展一个类的行为。而通常的方式是继承和多态。

    在架构层级,我们并不会变更系统的一部分功能(可能是最适用于当前架构的进程,守护进程,服务,或者微服务),而是通过新增功能的方式来复用已完成的代码。为了不对现有的部分做出变更,系统需要做到完全的解耦。接下来的内容将聚焦于事件驱动系统,并以消息队列实现服务间通信。消息队列 可以是ActiveMQ, RabbitMQ, ZeroMQ, Kafka或者其他服务,我将以Kafka的话语体系来进行描述,如主题(Topic),发布者,订阅者,以及类似Kafka的多个订阅者共享相同主题的能力。

    一、消息系统

    上图是一个一般用例:发布者向主题发布消息(或者事件),多个订阅者可以从主题处获得该事件。箭头指示了通信的流向。假定发布者和订阅者都是微服务的话,双层的圆角矩形代表某一特定微服务的多个实例。在本例中的四个微服务:发布者,订阅者1,订阅者2,订阅者n,每个微服务都有多个实例。

    二、具体示例

    举一个具体的例子。假设我们在一家汽车租赁公司工作,并负责建立一个车辆的可用性系统。整个租赁流程的简化视图如下:

     第1步,车辆租赁:包含租赁协议的签订和客户选车的过程。随即可用的车辆数减1。
    第2步,客户用车:客户在一定的时间范围内使用租赁的车辆。
    第3步,车辆归还:车辆的归还和签到。随即可用的车辆数加1。

    其中第1步和第3步都需要将租赁协议入库,因此我们可以设计一个事件,RentalAgreementSaved,在保存数据时触发。这一事件将被存储在RentalAgreementSaved主题中。因此到目前为止,共有两个发布者向主题发送消息,一个是CarRental微,另一个是CarCheckin微服务。

     

    下面来定义消息的内容。鉴于本主题的意图是为了表征租赁协议的保存,因此所需的最小信息量即协议ID。但系统的使命是跟踪车辆的可用性,最好还是设置一个Status字段。这一字段可以有两个值:

    激活状态。代表客户正在使用车辆。
    关闭状态。代表客户已经归还了车辆并进行了签到。

    CarRental微服务可以选用如下的JSON数据结构:

    {
    "Status":"Active",
    "RentalAgreementID":1234
    }

    CarCheckin微服务对应的数据结构是:

    {
    "Status":"Closed",
    "RentalAgreementID":1234
    }

    Status字段本应从数据库读取,并通过协议ID加载租赁协议,但因为我们只关心车辆的可用性,直接在JSON消息中写入协议ID更简单,性能也更好。这一点在后文还会提到。

    有了消息发布者和消息的格式,我们就可以完成下面的图表:

     

     CarAvailability微服务会对发送给RentalAgreementSaved主题的消息进行消费:如果Status是“激活状态”,就减1,如果Status是“关闭状态”,就加1。

  • 相关阅读:
    Informix日期获取上周上月昨天去年SQL
    PDI-KETTLE-4 使用Kettle完成通用DB生成指定文件并通过FTP上传
    日常问题解决记录二:DOS下切换盘符和工作目录
    PDI-KETTLE-3:数据库连接
    window下安装node.js
    【原创】正则断言的使用--为自动生成的get方法添加注解字段
    【原创】文本工具的使用--根据数据库字段快速生成该表对应的Model类属性
    【原创】字符串工具类--驼峰法与下划线法互转
    【原创】字符串工具类--获取汉字对应的拼音(全拼或首字母)
    【原创】关于oracle11G空表无法导出问题的解决方法
  • 原文地址:https://www.cnblogs.com/bangandwolf/p/11050257.html
Copyright © 2020-2023  润新知