微服务设计模式:防腐层(Anti-corruption layer)_琦彦-CSDN博客

标签: | 发表时间:2020-11-04 19:14 | 作者:
出处:https://blog.csdn.net

微软:微服务设计模式

2017年,微软  AzureCAT 模式和实践团队在  Azure 架构中心发布了  9 个新的微服务设计模式,并给出了这些模式解决的问题、方案、使用场景、实现考量等。微软团队称这 9 个模式有助于更好的设计和实现微服务,同时看到业界对微服务的兴趣日渐增长,所以也特意将这些模式记录并发布。

下图是微软团队建议如何在微服务架构中使用这些模式:

微软:微服务设计模式

 

文中提到的9 个模式包括:外交官模式(Ambassador),防腐层(Anti-corruption layer),后端服务前端(Backends for Frontends),舱壁模式(Bulkhead),网关聚合(Gateway Aggregation),网关卸载(Gateway Offloading),网关路由(Gateway Routing),挎斗模式(Sidecar)和绞杀者模式(Strangler)。这些模式绝大多数也是目前业界比较常用的模式,如:

  • 外交官模式(Ambassador)可以用与语言无关的方式处理常见的客户端连接任务,如监视,日志记录,路由和安全性(如 TLS)。
  • 防腐层\防损层(Anti-corruption layer)介于新应用和遗留应用之间,用于确保新应用的设计不受遗留应用的限制。
  • 后端服务前端(Backends for Frontends)为不同类型的客户端(如桌面和移动设备)创建单独的后端服务。这样,单个后端服务就不需要处理各种客户端类型的冲突请求。这种模式可以通过分离客户端特定的关注来帮助保持每个微服务的简单性。
  • 舱壁模式(Bulkhead)隔离了每个工作负载或服务的关键资源,如连接池、内存和 CPU。使用舱壁避免了单个工作负载(或服务)消耗掉所有资源,从而导致其他服务出现故障的场景。这种模式主要是通过防止由一个服务引起的级联故障来增加系统的弹性。
  • 网关聚合(Gateway Aggregation)将对多个单独微服务的请求聚合成单个请求,从而减少消费者和服务之间过多的请求。
  • 挎斗模式(Sidecar)将应用程序的辅助组件部署为单独的容器或进程以提供隔离和封装。

设计模式是对针对某一问题域的解决方案,它的出现也代表了工程化的可能。随着微服务在业界的广泛实践,相信这个领域将会走向成熟和稳定,笔者期望会有更多的模式和实践出现,帮助促进这一技术的进一步发展。

本文,主要介绍 防腐层(Anti-corruption layer)模式

防腐层(Anti-corruption layer)

在微服务(Microservices)架构实践中,人们大量地借用了DDD中的概念和技术,比如一个微服务应该对应DDD中的一个限界上下文(Bounded Context);在微服务设计中应该首先识别出DDD中的聚合根(Aggregate Root);还 有在微服务之间集成时采用DDD中的防腐层(Anti-Corruption Layer, ACL)。

防腐层(Anti-corruption layer,简称 ACL 介于新应用和遗留应用之间,用于确保新应用的设计不受老应用的限制。 是一种在不同应用间转换的机制。

创建一个 防腐层,以根据客户端自己的域模型为客户提供功能。该层通过其现有接口与另一个系统进行通信,几乎不需要或不需要对其进行任何修改。因此, 防腐层隔离不仅是为了保护您免受混乱的代码的侵害,还在于分离不同的域并确保它们在将来保持分离。

防腐层是将一个域映射到另一个域,这样使用第二个域的服务就不必被第一个域的概念“破坏”。

不共享相同语义的不同子系统之间实施外观或适配器层。 此层转换一个子系统向另一个子系统发出的请求。 使用 防腐层(Anti-corruption layer)模式可确保应用程序的设计不受限于对外部子系统的依赖。  防腐层(Anti-corruption layer)模式最先由 Eric Evans 在 Domain-Driven Design(域驱动的设计)中描述。

防腐层(Anti-corruption layer)提出背景

大多数应用程序依赖于其他系统的某些数据或功能。 例如,旧版应用程序迁移到新式系统时,可能仍需要现有的旧的资源。 新功能必须能够调用旧系统。 逐步迁移尤其如此,随着时间推移,较大型应用程序的不同功能迁移到新式系统中。

这些旧系统通常会出现质量问题,如复杂的数据架构或过时的 API。 旧系统使用的功能和技术可能与新式系统中的功能和技术有很大差异。 若要与旧系统进行互操作,新应用程序可能需要支持过时的基础结构、协议、数据模型、API、或其他不会引入新式应用程序的功能。

保持新旧系统之间的访问可以强制新系统至少支持某些旧系统的 API 或其他语义。 这些旧的功能出现质量问题时,支持它们“损坏”可能会是完全设计的新式应用程序。

不仅仅是旧系统,不受开发团队控制的任何外部系统(第三方系统)都可能出现类似的问题。

解决方案

在不同的子系统之间放置防损层以将其隔离。 此层转换两个系统之间的通信,在一个系统保持不变的情况下,使另一个系统可以避免破坏其设计和技术方法。

在不同的子系统之间放置防损层以将其隔离

 

上图显示了采用两个子系统的应用程序。 

子系统 A 通过防损层调用子系统 B。 子系统 A 与防损层之间的通信始终使用子系统 A 的数据模型和体系结构。防损层向子系统 B 发出的调用符合该子系统的数据模型或方法。 防损层包含在两个系统之间转换所必需的所有逻辑。

该层可作为应用程序内的组件或作为独立服务实现。

Anti-corruption layer注意事项

  • 防损层可能将延迟添加到两个系统之间的调用。
  • 防损层将添加一项必须管理和维护的其他服务。
  • 请考虑防损层的缩放方式。
  • 请考虑是否需要多个防损层。 可能需要使用不同的技术或语言将功能分解为多个服务,或者可能因其他原因对防损层进行分区。
  • 请考虑如何管理与其他应用程序或服务相关的防损层。 如何将其集成到监视、发布和配置进程中?
  • 确保维护并可以监视事务和数据一致性
  • 请考虑防损层是要处理不同子系统之间的所有通信,还是只需处理部分功能。
  • 如果防损层是应用程序迁移策略的一部分,请考虑该层是永久性的,还是在迁移所有旧功能后即会停用。
  • 经常和绞杀者模式(strangler)一起使用

Anti-corruption layer使用场景

在以下情况下使用此模式:

  • 迁移计划为发生在多个阶段,但是新旧系统之间的集成需要维护
    • 很多人一看到旧系统就想要赶快替换掉他,但是请不要急著想著去替换旧系统,因为这条路充满困难与失败,而且 旧系统通常反而是系统目前最赚钱的部分。更好的做法是在使用旧系统时包上一层 ACL,让你的开发不受影响,甚至可以一点一滴的替换旧系统的功能,达到即使不影响目前功能下也能开发新功能,达到重构的效果!
  • 两个或更多个子系统具有不同的语义,需要对外部上下文的访问进行一次转义
    • 例如:对接第三方系統。缴费软件中的收银台系统,需要对接不同的支付方式(支付宝、各个银行、信用卡等),这是就需要 收银台系统充当一个Anti-corruption layer,将用户的缴费支付信息,转换成各个三方支付系统需要的数据格式。
  • 如果内部多个组件对外部系统需要访问,那么可以考虑将其放到通用上下文中。
    • 例如:我们有一个抽奖平台,包含有现金券、折扣券、外卖券、出行券等组件,但他们都需要对接用户信息服务,这时就需要在抽奖平台中,搭建一个 Anti-corruption layer,作为抽奖平台对接用户信息的通用适配层。

如果新旧系统之间没有重要的语义差异,则此模式可能不适合。

Anti-corruption layer 示例1:JDK集合

在 JDK1.0 时我们用的集合还是 Vector(后来推荐使用 ArrayList),我们用的迭代器还是 Enumeration(后来推荐使用 Iterator)。现在我们需要一个适配器,搭建 Anti-corruption layer (EnumerationAdapter ),让 Vector 也能使用 Iterator 迭代器,即在 Enumeration 和 Iterator 之间做适配。

      /**
 * 1、Iterator 是新版本的迭代器。
 * 2、Enumeration 是旧版本的迭代器。
 * 3、EnumerationAdapter 是适配者(Adapter)角色,相当于Anti-corruption layer 在 Enumeration 和 Iterator 之间做适配
 */
public class EnumerationAdapter implements Iterator {

    private Enumeration enumeration;

    public EnumerationAdapter(Enumeration enumeration) {
        this.enumeration = enumeration;
    }

    @Override
    public boolean hasNext() {
        return enumeration.hasMoreElements();
    }

    @Override
    public Object next() {
        return enumeration.nextElement();
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("remove");
    }
}

// main方法
public static void main(String[] args) {
	Vector vector = new Vector();
	vector.add("java");
	vector.add("python");
	vector.add("javaScript");
	Enumeration enumeration = vector.elements();
	Iterator iterator = new EnumerationAdapter(enumeration);
	while (iterator.hasNext()) {
		System.out.println(iterator.next());
	}
}

 

Anti-corruption layer 示例2--企业员工管理系统新旧版本对接

  • 在企业员工管理系统中,我们经常需要通过ID查询雇员信息(EmployeeAccessService.findEmployee)
  • 但,我们在企业员工管理系统版本迭代中,可能存在老员工的信息在旧版本企业员工管理系统,新员工的信息在新版本企业员工管理系统。
  • 当我们查询老员工的信息,就需要委托给EmployeeAccessAdapter适配器,从旧版本企业员工管理系统(EmployeeAccessFacade)中获取一个员工信息。
  • 并通过EmployeeAccessTranslator,以将旧版本员工信息转换为应用程序模型中的域对象。

 

EmployeeAccessService(查询雇员信息

          public Employee findEmployee(String empID){
    return adapter.findEmployee(empID);
}

EmployeeAccessAdapter ( Anti-corruption layer,对接旧版本企业员工管理系统

          // 旧版本 员工信息
private EmployeeAccessFacade facade;

public Employee findEmployee(String empID){
    EmployeeAccessContainer container = facade.findEmployeeAccess(empID);
    return translator.translate(container);
}

EmployeeAccessTranslator(将旧版本员工信息转换为应用程序模型中的域对象

          public Employee translate(EmployeeAccessContainer container){
    Employee emp = null;
    if (container != null) {
        employee = new Employee();
        employee.setEmpID(idPrefix + container.getEmployeeDTO().getEmpID());
        ...(more complex mappings)

 

参考链接:

https://docs.microsoft.com/en-us/azure/architecture/

https://stackoverflow.com/questions/909264/ddd-anti-corruption-layer-how-to

https://docs.microsoft.com/zh-cn/azure/architecture/patterns/strangler

https://ithelp.ithome.com.tw/articles/10218591

https://tech.meituan.com/2017/12/22/ddd-in-practice.html

相关 [微服务 设计模式 anti] 推荐:

微服务设计模式:防腐层(Anti-corruption layer)_琦彦-CSDN博客

- -
 AzureCAT 模式和实践团队在.  Azure 架构中心发布了.  9 个新的微服务设计模式,并给出了这些模式解决的问题、方案、使用场景、实现考量等. 微软团队称这 9 个模式有助于更好的设计和实现微服务,同时看到业界对微服务的兴趣日渐增长,所以也特意将这些模式记录并发布. 下图是微软团队建议如何在微服务架构中使用这些模式:.

[ 翻译 ] 微服务架构及设计模式

- -
本文介绍了主流常见的微服务模式. 因此,了解如何处理微服务架构(MSA)以及一些微服务设计模式,一个微服务架构的一些通用目标或者设计原则是很有价值的. 下面是在微服务架构方案中值得考虑的四个目标[1]. 1、缩减成本:MSA将会降低设计、实现和维护IT服务的总体成本. 2、加快发布速度:MSA将会加快服务从想法到部署的落地速度.

微服务架构设计模式 - XuMinzhe - 博客园

- -
单体地狱的银弹-微服务架构. 大型的复杂应用程序可以持续交付和持续部署. 每个服务都相对较小并容易维护. 分布式系统带来的各种复杂性. 开发者需要思考到底应该在应用的什么阶段使用微服务架构. 随着网络基础设施的高速发展,以及越来越多的个体接入互联网,在考虑构建支持海量请求以及多变业务的软件平台时,微服务架构成为多数人的首选.

微服务架构及设计模式 - DockOne.io

- -
【编者的话】本文作者详细介绍了微服务架构里一些常见的设计模式和它们各自的使用场景. 因此,了解如何处理微服务架构(MSA)以及一些微服务设计模式,一个微服务架构的一些通用目标或者设计原则是很有价值的. 下面是在微服务架构方案中值得考虑的四个目标. 缩减成本:MSA 将会降低设计、实现和维护IT服务的总体成本.

The Open Session In View Anti-Pattern - Vlad Mihalcea

- -
An anti-pattern (or antipattern) is a common response to a recurring problem that is usually ineffective and risks being highly counterproductive.. When using JPA and Hibernate, the Fetching policy can have one of the biggest impacts on application performance, and, as explained in my.

Android Java层的anti-hooking技巧

- - WooYun知识库
原文: http://d3adend.org/blog/?p=589. 一个最近关于检测native hook框架的方法让我开始思考一个Android应用如何在Java层检测Cydia Substrate或者Xposed框架. 下文所有的anti-hooking技巧很容易就可以被有经验的逆向人员绕过,这里只是展示几个检测的方法.

Scala设计模式

- - ITeye博客
       我的话: 在国外网站上看到一篇文章,里面详细描述了很多设计模式,并且用Java及Scala两种语言描述,清晰的让我们看到各种常规的设计模式,在Scala中是如何在语言特性层面直接支持的. 基于文章很nice,我利用今天的空闲时间将其翻译,希望大家能一起学习,讨论. 翻译比较倡促,也就两小时左右,有何不当,请在下面留言指出.

Spring设计模式

- - 行业应用 - ITeye博客
springMVC通常采用属性注入的IOC方式和AOP织入方式相结合实现依赖注入 同时使用强制代理方式,代理类或者接口. 这里又涉及到单例模式(注入的类或者接口在容器中只存在一个)、工厂模式(通过反射实现类实例化过程的公用化)、楼上所说的装饰模式属于AOP织入的一部分. 想了解spring先从IOC和AOP开始吧.

产品经理,为什么应该尽早考虑Anti策略?

- - 雷锋网
Anti策略是针对互联网产品内注册用户可能产生的一切不符合网站定位和规则的行为的审核规则,旨在更高效地通过非人工的方式干掉非法的内容、用户以在某种程度上保证产品的“调性”和用户使用体验. 比如一个刚上线的社区产品,当刚有一点用户的时候就开始有大量的水军来灌水发招手打字员或网络兼职的信息. 这很有可能就让这个产品一时间没办法用而运营手工又人工忙不过来导致这个产品“元气大伤”.

“另类” 设计模式

- Sean Lee - 酷壳 - CoolShell.cn
下面这篇文章来自这里:http://www.lsd.ic.unicamp.br/~oliva/fun/prog/resign-patterns,这篇文章有点意思了,山寨了我们著名的Design Pattern. 这篇文章并不是很容易翻译,也许我翻译的不好,大家多指正. 另外,这篇文章将失去原有的趣味在于其使用了经典设计模式的单词很相似的单词,一走眼你还以为是正二八经的设计模式.