微服务设计的原则:IDEALS,而不是SOLID( 三 )

  • 持续交付:这是缩短从提交到部署间隔并保持代码质量的必要实践 。传统的CICD工具有Jenkins、Gitlab CI/CD、Bamboo、GoCD、CircleCI和Spinnaker 。最近,Weaveworks和Flux等GitOps工具被添加到这个领域,将CD和IaC结合起来 。
  • 配置管理:将配置属性存储在微服务部署单元之外,并且易于管理 。
  •  
    四、事件驱动微服务架构风格用于创建后端服务,这些服务通常使用以下三种类型的方式进行调用:
    • HTTP调用(REST服务)
    • 使用特定于平台的组件技术进行类RPC调用,如gRPC或GraphQL
    • 通过消息中间件处理异步消息
    前两个通常是同步的,HTTP调用也是最常见的方式 。通常,服务需要调用其他服务进行组合,太多时候,组合中的服务调用是同步的 。如果异步,需要连接和接收Queue/Topic里的消息,那么我们将创建一个事件驱动的体系结构 。(我们可以讨论消息驱动和事件驱动的区别,但都可以表示网络上的异步通信,使用消息中间件产品(Apache Kafka、RabbitMQ和Amazon SNS)提供的Queue和Topic)
     
    事件驱动体系结构的一个重要好处是提高了可伸缩性和吞吐量 。这是因为:消息发送者在等待响应时不会被阻塞,并且同一个消息/事件可以由多个接收者以发布-订阅的方式并行使用 。
    事件驱动的微服务
    IDEALS中的E就表示使用事件驱动对微服务进行建模 。因为他们更能满足当今软件解决方案的可伸缩性和性能要求,这种设计还促进了松耦合,因为消息发送方和接收方——微服务——是对立的,彼此不了解 。可靠性也得到了提升,因为这个设计可以处理微服务的临时中断,当微服务恢复后可以处理排队中的消息 。
    但事件驱动的微服务,也称为反应式微服务,也会带来挑战,比如异步处理和并行执行,可能需要同步点和相关标识符 。设计需要考虑错误和丢失的消息——校正事件和撤销数据更改的机制(如Saga模式)通常是必须的 。对于事件驱动体系结构带来的面向用户的事务,应仔细考虑用户体验,以使最终用户了解进度和事故 。
     
    五、可用性胜于一致性CAP理论本质上给了我们两个选择:可用性或者一致性 。我们看到业界为了让我们选择可用性而付出了巨大努力,从而最终实现一致性 。原因很简单:今天的最终用户不会容忍服务不可用 。假如一个网络商店,如果我们在浏览产品时显示的库存量和购买时更新的实际库存量之间强制执行强一致,那么数据变更将会带来巨大的开销,如何任何更新库存的服务暂时无法访问,那么页面无法显示库存信息,结账将停止服务 。相反,如果选择可用性,用户浏览产品时显示的库存量和购买时更新的实际库存量之间会有偶尔的不一致 。当用户在下单买时,然后再去查询真实的库存量,如果没有库存,再提示用户没有库存 。从用户的角度来看,这个场景比由于系统要实现强一致而让整个系统不可用或超级慢对所有用户来说要好很多 。
     
    有些业务操作确实需要很强的一致性 。然而,正如Pat Helland指出,当你面对你是想要正确?还是想要现在?的问题时,人们通常想要的是现在而不是正确的答案时,就需要考虑强一致 。
     
    最终一致性的可用性
    对于微服务来说,保证可用性选择的主要策略是数据复制 。可以采用不同的设计模式,有时可以组合使用 。
    • 服务数据复制模式:当微服务需要访问属于其他应用程序的数据(而API调用不适合获取数据)时,使用此基本模式 。我们创建该数据的副本,并使其随时可供微服务使用 。该解决方案还需要一种数据同步机制(如ETL工具/程序、发布-订阅消息传递、物化视图),该机制将定期或基于触发器使副本与主数据库保持一致 。
    • 命令查询责任分离(CQRS)模式:这里我们将更改数据(Command)的操作设计与实现和只读数据(Query)的操作分开 。CQRS通常建立在服务数据复制的基础上,用于提高查询的效率 。
    • 事件源(Event Source)模式:我们不在数据库中存储对象的当前状态,而是存储影响该对象的仅附加的、不可变的事件序列 。当前状态是通过回放事件获得,这样做是为了提供数据的“查询视图” 。因此,事件源通常建立在CQRS设计的基础上 。
     
    我们经常使用的CQRS模式通常如下图所示:一个可以更改数据的HTTP请求由后台一个REST服务处理,该服务可以操作一个集中式的Oracle数据库 。其他只读的HTTP请求转到另一个后台服务,该服务可以从基于文本的Elasticsearch数据存储中获取数据 。一个Spring Batch Kubernetes cron任务定期将在Oracle数据库中的变更同步到ES中,这个设计使用两个数据存储之间的最终一致性 。即使Oracle DB和cron任务不起作用,查询服务也是可用的 。


    推荐阅读