软件体系架构阅读笔记十一

1. 读者容错模式数据库

读者容错模式(Tolerant Reader)指微服务化中服务提供者和消费者之间如何对接口的改变进行容错。从字面上来说,消费者须要对提供者提供的功能进行兼容性设计,尤为对服务提供者返回的内容进行兼容,或者解决在服务提供者改变接口或者数据的格式的状况下,如何让服务消费者正常运行。缓存

任何一个产品在设计时都没法预见未来可能增长的全部需求,服务的开发者一般经过迭代及时地增长新功能,或者让服务提供的API天然地演进。不过,服务提供者对外提供的接口的数据格式的改变、增长和删除,都会致使服务的消费者不能正常工做。安全

所以,在服务消费者处理服务提供者返回的消息的过程当中,须要对服务返回的消息进行过滤,只提取本身须要的内容,对多余或者未知的内容采起抛弃的策略,而不是硬生生地抛错处理。架构

在实现过程当中不推荐使用严格的校验策略,而是推荐使用宽松的校验策略,即便服务消费者拿到的消息报文发生了改变,程序也只需尽最大努力提取须要的数据,同时忽略不可识别的数据。只有在服务消费者彻底不能识别接收到的消息,或者没法经过识别的信息继续处理流程时,才能抛出异常。框架

服务的消费者的容错模式忽略了新的消息项、可选的消息项、未知的数据值及服务消费者不须要的数据项。运维

笔者当前在某个支付公司工做,公司里几乎每一个业务都须要使用枚举类型,在微服务平台下,笔者在研发流程规范中定义了一条枚举值使用规范:分布式

在服务接口的定义中,参数可使用枚举值,在返回值的DTO中禁止使用枚举值。微服务

这条规范就是读者容错模式在实践中的一个实例,之因此在参数中容许使用枚举值,是由于若是服务的提供者升级了接口,增长了枚举值,若服务的消费者并无感知,则服务的消费者得知新的枚举值就能够传递新的枚举值了;可是若是接口的返回DTO中使用了枚举值,而且由于某种缘由增长了枚举值,则服务消费者在反序列化枚举时就会报错,所以在返回值中咱们应该使用字符串等互相承认的类型,来作到双方的互相兼容,并实现读者容错模式。设计

2. 消费者驱动契约模式blog

消费者驱动契约模式用来定义服务化中服务之间交互接口改变的最佳规则。

服务契约分为:提供者契约、消费者契约及消费者驱动的契约,它从指望与约束的角度描述了服务提供者与服务消费者之间的联动关系。

  • 提供者契约:是咱们最经常使用的一种服务契约,顾名思义,提供者契约是以提供者为中心的,提供者提供了什么功能和消息格式,各消费者都会无条件地遵照这些约定,不论消费者实际须要多少功能,消费者接受了提供者契约时,都会根据服务提供者的规则来使用服务。
  • 消费者契约:是对某个消费者的需求进行更为精确的描述,在一次具体的服务交互场景下,表明消费者须要提供者提供功能中的哪部分数据。消费者契约能够被用来标识现有的提供者契约,也能够用来发现一个还没有明确的提供者契约。
  • 消费者驱动的契约:表明服务提供者向其全部当前消费者承诺遵照的约束。一旦各消费者把本身的具体指望告知提供者,则提供者不管在什么时间和场景下,都不该该打破契约。

在现实的服务交互设计中,上面这三种契约是同时存在的,笔者所在的支付平台里,交易系统在完成一笔支付后,须要到帐务系统为商户入帐,在这个过程当中,服务契约表现以下。

  • 生产者契约:帐务系统提供Dubbo服务化接口,参数为商户帐户ID、入帐订单号和入帐金额。
  • 消费者契约:帐务系统返回DTO,包含商户帐户ID、入帐订单号、入帐金额、入帐时间、帐务流水号、入帐状态等,而交易系统只需使用其中的入帐订单号和入帐状态。
  • 消费者驱动的契约:为了保证资金安全,交易系统做为入帐的发起者向帐务提出要求,须要帐务作幂等和滤重处理,对重复的入帐请求进行拦截;帐务系统在接受这个契约后,即便未来有任何改变,也不能打破这个限制,不然就会形成资金的损失,这在金融系统中是最严重的问题。

服务之间的交互须要使用的三种服务契约以下图所示。

 

 

从上图能够看到,服务提供者契约是服务提供者单方面定下的规则,而一个消费者契约会成为提供者契约的一部分,多个服务消费者能够对服务提供者提出约束,服务提供者须要在未来遵照服务消费者提出的契约,这就是消费者驱动的契约。

3. 去数据共享模式

与SOA服务化对比,微服务是去ESB总线、去中心化及分布式的;而SOA仍是以ESB为核心实现遗留系统的集成,以及基于Web Service为标准实现的通用的面向服务的架构。在微服务领域,微服务之间的交互经过定义良好的接口来实现,不容许使用共享数据来实现。

在实践的过程当中,有些方案的设计使用缓存或者数据库做为两个微服务之间的纽带,在业务流程的处理过程当中,为了处理简单,前一个服务将中间结果存入数据库或者缓存,下一个服务从缓存或者数据库中拿出数据继续处理。处理流程以下图所示。

 

 

这种交互流程的缺点以下。

  • 使得微服务之间的交互除了接口契约,还存在数据存储契约。
  • 上游的数据格式发生变化时,可能致使下游的处理逻辑出现问题。
  • 多个服务共享一个资源服务,对资源服务的运维难以划清职责和界限。
  • 在作双机房独立部署时,须要考虑服务和资源的路由状况,跨机房的服务调用不能使用独立的资源部署模式,所以难以实现服务自治。

所以,在设计微服务架构时,必定不要共享缓存和数据库等资源,也不要使用总线模式,服务之间的通讯和交互只能依赖定义良好的接口,一般使用RESTful样式的API或者透明的RPC调用框架。

相关文章
相关标签/搜索