多年以来,咱们一直在寻找更好的方法来构建应用系统。咱们一直在学习已有的技术,尝试新技术,使用不一样的方式来构建IT应用系统,从而提升客户满意度和开发效率。html
Eric Evans的《领域驱动设计》一书帮助理解了用代码呈现真实世界的重要性,而且告诉咱们如何更好地进行建模。持续交付理论告诉咱们如何更有效地发布软件产品,并指出保持每次提交都可发布的重要性。基于对web的理解,咱们寻找到了机器与机器交互的更好方式。Alistair Cockburn的六边形架构理论把咱们从分层架构中拯救出来,从而可以更好地体现业务逻辑。借助虚拟化平台,可以按需建立机器并调整其大小,借助基础设施的自动化,咱们也很容易从一台机器扩展到多台。前端
随着领域驱动设计、持续交付、按需虚拟化、基础设施自动化、小型自治团队、大型集群系统这些实践的流行,微服务也应运而生。它并非被发明出来的,而生从现实世界中总结出来的一种趋势或模式。可是没有前面体积的这些概念,微服务也很难出现。vue
不少组织发现细粒度的微服务架构能够帮助他们更快地交付软件,而且有更多机会尝试新技术。微服务在技术决策上给咱们极大的自由度,使咱们可以更快地响应不可避免的变化。java
微服务架构是一种架构模式,提倡将单一应用程序划分红一组小的服务,每一个服务运行在其独立的进程中,服务间采用轻量级的通讯机制互相沟通(一般是基于HTTP协议的RESTful API)。每一个服务都围绕着具体业务进行构建,而且可以被独立的部署到生产环境,类生产环境等。react
很小、专一于作好一件事git
随着新功能的增长,代码库会愈来愈大。时间久了代码库会很是庞大,以致于想要知道该在什么地方作修改都很困难。尽管咱们想在巨大的代码库中作到清晰地模块化,但事实上这些模块之间的界限很难维护。类似的功能代码开始在代码库中随处可见,使得修复bug或实现更加困难。程序员
在单块系统内,一般会建立一些抽象层或者模块来保证代码的内聚性,从而避免上述问题。 内聚性是指将相关代码放在一块儿在考虑使用微服务的时候,内聚性这一律念很重要。github
Robert C.Martin有一个对单一职责原则的论述:把因相同缘由而变化的东西聚合到一块儿,而把因不一样缘由而变化的东西分离开来。该论述很好的强调了内聚性这一律念。微服务将这个理念应用在独立的服务上,根据业务的边界来肯定服务的边界,这些就很容易肯定某个功能代码应该放在那里。并且因为该服务专一于某个边界以内,所以能够很好地避免因为代码库过大衍生出的不少相关问题。web
微服务,最大的挑战就是三个原则:不要太大,不要过小,不要太紧密耦合redis
没有规定的微观概念,微服务不必定要小。
微服务架构风格是一种将单个应用程序开发为一套小型服务的方法,每一个小型服务都在本身的流程中运行,并于轻量级机制(HTTP)进行通讯。
这些服务围绕业务功能构建,能够用全自动部署机制独立部署。这些服务能够进行集中管理,能够用不一样的编程语言编写,并使用不一样的数据库存储技术。
足够小并且不过小,一旦一段代码再也不感受到太大了,它可能足够小了。
开发软件更快
主要应用程序是一个大型代码库,几个小型开发团队试图为不一样目的构建功能。意味着每一次变动都必须努力知足不一样的群体。
让不一样的开发人员团队共享相同的代码库也意味着的代码以难以想象的方式不断变得更加复杂。随着代码库变得愈来愈大,团队中没有人能够拥有它而且确保全部部件都按照最佳方式进行组织和组合。
使得部署变得困难,对咱们的应用程序进行单行更改仍然须要部署整个过程以推进更改。因为咱们的大型应用程序是高风险的,质量保证流程增加
经过微服务架构,但愿可以将代码分开,以便不一样的开发团队能够彻底拥有它们。这将使团队可以更快地进行建立,而无需繁琐的设计,审查、部署流程。还但愿经过减小开发人员处理较小的代码库,代码库将更容易开发,测试和保持良好的组织。
灵活应对技术选择
经过微服务架构,但愿将个别服务保持在较小状态意味着用更好的实现来替换它们的成本将更容易管理。也但愿可以为每项工做选择合适的工具,而不是一刀切的方法。能够灵活地在咱们认为合适的不一样应用程序中使用多种技术。
微服务缺点
开发,托管和管理众多服务须要大量开销。在少数几个进程上运行的单个总体能够轻松地转换为几个服务的几十个进程,须要负载均衡器,消息传递层和群集以实现弹性。
微服务涉及分布式系统,这些系统引入了许多问题,例如:网络延迟、容错、事务、不可靠的网络和异步性
构建为统一单元。一般由三部分组成:数据库、客户端界面(HTML)、服务端应用。
服务端应用将处理HTTP请求,执行逻辑,从数据库检索和更新数据,以及填充要发送到浏览器的HTML视图
一般是一个庞大的代码库。服务器端的应用逻辑,前端客户端逻辑,后台做业等都在同一个代码库定义。开发人员想要进行更改或更新,须要一次构建和部署整个堆栈
优势:
缺点:
微服务架构是指将单个应用程序开发为一套小型服务的概念,而不是将它们开发为一个大型的“总体”
每一个分解的个性化的服务都在本身的进程上运行,与轻量级机制(HTTP)进行通讯。彻底成熟的微服务可独立部署,但必要时能够协同工做
优势:
缺点:
考虑几个关键因素,以下
适合使用单片应用
适合微服务
使用微服务开发新系统的核心好处之一是该架构容许开发人员独立构建或修改单个组件时,当涉及最小化每一个API之间的回调数量时会出现问题
避免任意规则
设计和建立微服务时,不须要陷入使用任意规则的陷阱。下面的规则,并非肯定微服务边界的正确方法
精心设计的服务特色
高内聚,松耦合
高内聚是指一个软件模块是由相关性很强的代码组成
特征1:不与其余服务共享数据库表
若是多个服务引用相同的表,那么在设计微服务时就不适合,由于可能意味着你的数据库是耦合的来源。
开发新服务时使用的主要基本原则之一就是它们不该该跨越数据库边界。每一个服务都应该依赖于本身的一组底层数据存储。这使得咱们能够集中访问控制,审计日志记录,缓存逻辑等
若是数据库表的一个子集与数据集的其他部分没有或不多有链接,那么组件能够呗隔离到一个单独的API或单独的服务中,这是一个强烈信号
每一个服务应该有本身的表和永远不该该共享数据库表
特征2:具备最少许的数据库表
微服务的理想大小应该足够小,每一个数据库表也是同样的。最佳状况是一个或两个数据库表
特征3:考虑有状态和无状态
设计微服务时,须要考虑它是否须要访问数据库,或者它是否处理过TB级别数据的无状态服务。
经过定义服务的输入和输出来定义服务的边界。有时候服务是网络API,但它也多是使用文件并在数据库中生成记录的进程
特征4:考虑数据可用性需求
设计微服务时,须要记住那些服务将依赖于此新服务,以及在该数据不可用时的整个系统的影响。
考虑到这一点,也能够正确地设计此服务的数据备份和恢复系统
特征5:单一的真实来源
设计服务时,让其称为系统中某些内容的惟一真实来源。
注意事项
整个团队能够专门拥有服务,在肯定边界时,组织性就会发挥做用。
还有两个须要考虑的因素:独立的发布计划和不一样的正常运行时间
如何判断服务是否过小或未正肯定义
第一个指标是服务之间的任何过分依赖,若是两个服务不断地相互呼叫,那么这是一个强烈的耦合指示和一个信号,可能会更好地组成一个服务
第二个,若是设置服务的开销大于使其独立的好处
#
使用Java搭建微服务框架语言
未使用微服务框架问题分析:
统一用户认证平台
统一用户认证平台用于集中管理组织与人员信息,提供统一标准的人员主数据。经过SOA服务总线与各业务系统进行集成,同时为单点登陆提供统一的身份认证信息。
统一用户认证平台与企业邮箱,企业微信息,AD域进行集成。实现一个帐号,全网登陆
Spring Framework 基础框架支持
Spring Boot 做为服务的开发框架
Spring Cloud 进行微服务设计与开发
Spring Cloud Netflix 为Spring Boot应用提供Netflix OSS集成
Eureka 做为云服务器中服务注册与发现中心,实现负载均衡
Feign 进行服务访问,简化Eureka访问参数
Ribbon 实现Eureka集群的负载均衡
Hystrix 进行服务容错处理,具有回退机制和断路器功能的线程和信号隔离,请求缓存\打包以及监控和配置
Zuul 做为服务网关
ZooKeeper 实现高度可靠的分布式协调
Dubbo 阿里开源高性能优秀服务框架。
部署
Jenkins,GitLab CI 自动化部署
Docker 集装箱部署
为现代基于Java语言的企业应用提供全面的编程和配置模型-在任何类型部署平台上。
Spring的一个关键要素是应用程序级别的基础架构支持:Spring专一于企业应用程序的管道,以便团队能够专一于应用程序级人物逻辑,而无需与特定部署环境创建没必要要的联系。
特征
核心技术:依赖注入,事件,资源,i18n,验证,数据绑定,类型转换,SpEL,AOP。
测试:模拟对象,TestContext框架,Spring MVC测试,WebTestClient
。
数据访问:事务,DAO支持,JDBC,ORM,编组XML。
Spring MVC和 Spring WebFlux Web框架。
集成:远程处理,JMS,JCA,JMX,电子邮件,任务,调度,缓存。
语言:Kotlin,Groovy,动态语言。
#
能够轻松建立独立的,生产级的基于Spring的应用程序。
为Spring平台及第三方库提供开箱即用的设置。多数Spring应用只须要不多的配置。
特征
#
为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁定,领导选举,分布式会话,集群状态)
使用Spring Cloud开发人员能够快速搭建实现这些模式的服务和应用程序。适用于任何分布式环境,包括开发人员本身的笔记本、数据中心和Cloud Foundry等托管平台
特征
Spring Cloud专一于为典型用例提供良好的开箱即用体验,并为其余用户提供可扩展性机制
采用了一种很是具备声明性的方法,一般只须要更改类路径和/或注释便可得到大量内容
主要项目
Spring Cloud Config:git存储库支持的集中式外部配置管理。配置资源直接映射到Spring
Spring Cloud Netflix:与各类Netflix OSS组件集成(Eureka,Hystrix,Zuul,Archaius)
Spring Cloud Bus:用于将服务和服务实例与分布式消息传递链接在一块儿的事件总线,用于在群集中传播状态更改
Spring Cloud Cloudfoundry:将应用程序与Prvotal Cloud Foundry集成。提供服务发现实现,还能够轻松实现SSO和OAuth2保护的资源
Spring Cloud Open Service Broker:提供构建实现Open Service Broker API的服务代理的起点
Spring Cloud Cluster:领导者选举和共同的状态模式与Zookeeper,Redis,Hazelcast,Consul的抽象和实现
Spring Cloud Consul:Hashicorp Consul的服务发现和配置管理
Spring Cloud Security:Zuul代理中的负载均衡OAuth2 rest客户端和身份验证头中继续提供支持
Spring Cloud Sleuth:Spring Cloud应用程序的分布式跟踪,与Zipkin,HTrace和基于日志的跟踪兼容
Spring Cloud Data Flow:适用于现代运行时的可组合微服务应用程序的云本机编排服务。
Spring Cloud Stream:轻量级事件驱动的微服务框架,可快速构建可链接到外部系统的应用程序。在应用程序之间使用Kafka或RabbitMQ发送和接受消息的简单声明模型
Spring Cloud Stream App Starters:基于Spring Boot的Spring Integration应用程序,可提供与外部系统的集成
Spring Cloud Task:用于快速构建执行有限数据处理的应用程序。向应用程序添加功能和非功能的简单声明
Spring Cloud Task App Starters:Spring Boot应用程序,多是任何进程,包括不能永远运行的Spring Batch做业,在有限的数据处理后结束/中止
Spring Cloud Zookeeper:服务发现和配置管理
Spring Cloud AWS:与托管的Amazon Web Service轻松集成。
Spring Cloud Connectors:使各类平台中的PaaS应用程序能够轻松链接到数据库和消息代理等后端服务
Spring Cloud Starters:能够简化Spring Cloud用户的依赖管理
Spring Cloud CLI:用于在Groovy中快速建立Spring Cloud组件应用程序
Spring Cloud Contract:整体项目,包含帮助用户成功实施消费者驱动合同方法的解决方案
Spring Cloud Gateway:基于Project Reactor的只能可编程路由器
Spring Cloud OpenFeign:自动配置和Spring环境以及其余Spring编程模型习惯用法提供Spring Boot应用程序的集成
Spring Cloud Pipelines:固定部署管道,其中包含确保您的应用程序能够热部署而且轻松回滚出错的步骤
Spring Cloud Function:支持无服务器提供商之间的统一编程模型
#
Netflix OSS指Netflix Open Source Software
关注点是OOS中的Common Runtime Services & Libraries,包括为微服务提供支持的运行容器,类库和服务
Netflix OOS是一组开源的框架和组件库,是Netflix公司开发出来解决分布式系统的一些有趣的可扩展类库。对Java开发者来讲,是在云端环境中开发微服务的很是棒的工具代名词。在服务发现,负载均衡,容错等模式方面,都给出了很是重要的概念和解决方案。
组件和功能
Eureka:服务注册和服务发现
Archaius:分布式配置管理
Ribbon:客户端负载均衡
Hystrix:断路器,运行时提供延迟和容错的隔离
Karyon:实现云就绪Web服务的构建蓝图
Governator:扩展和实用程序库,可经过@PostConstruct和@PreDestory加强Google Guice以提供注入生命周期以及对对象生命周期的支持
Pranae:使其易于与NetflixOSS服务继承
Zuul:服务网关
Fenzo:Apache Mesos框架的调度程序Java库,支持用于调度优化的插件并促进集群自动扩展。
Spring Cloud Netflix
Spring Cloud Netflix经过自动配置和Spring环境以及其余Spring编程模型习惯用法为Spring Boot应用程序提供Netflix OSS集成。经过一些简单的注释,能够快速启用和配置应用程序内的常见模式,并使用通过实战考研的Netflix组件构建大型分布式系统。提供的模式包括服务发现(Eureka),断路器(Hystrix),智能路由(Zuul),客户端负载均衡(Ribbon)
特征
服务发现:能够注册Eureka实例,客户端可使用Spring管理的bean发现实例
服务发现:可使用声明性Java配置建立嵌入式Eureka服务器
断路器:Hystrix客户端可使用简单的注释驱动方法装饰器构建
断路器:带有声明性Java配置的嵌入式Hystrix仪表板
声明性REST客户端:Feign建立使用JAX-RS或Spring MVC注释修饰的接口的动态实现
客户端负载均衡器:Ribbon
外部配置:从Spring Environment到Archaius的桥接(使用Spring Boot约定启用Netflix组件的本机配置)
路由器和过滤器:Zuul过滤器的自动注册,以及反向代理建立的配置方法的简单约定
#
一种基于REST的服务,用于发现定位服务,以实现中间层服务器的负载平衡和故障转移。将此服务称为Eureka Server。
Eureka还附带了一个基于Java的客户端组件Eureka Client,使与服务的交互变得更加容易。客户端还有一个内置的负载均衡器,能够进行基本的循环负载均衡。在Netflix,一个更复杂的负载均衡器包装Eureka,根据流量,资源使用,错误条件等多种因素提供加权负载平衡,以提供卓越的弹性。
简单的多个服务,经过API调用会面临如下几个问题
服务发现是基于微服务架构的关键原则之一。尝试配置每一个客户端或某种形式的约定可能很是困难,很是脆弱。Eureka能够将服务器配置和部署为高可用性,每一个服务器将注册服务的状态复制到其余服务器。
使用服务发现框架Eureka能够实现如下功能
Eureka为咱们提供了以上的解决方案,分别为Eureka-server和Eureka-client两个部分。
Eureka提供服务注册服务发现功能,能够部署为Eureka-server集群。
Eureka-client的主要功能是将服务注册到Eureka-server,经过Eureka-server发现服务。
高可用性
Eureka服务器没有后端存储,可是注册表中的服务实例必须发送心跳包以保持注册更新,所以能够在内存中完成。
Eureka客户端还具备服务注册表缓存,当客户端获取注册表中的服务实例时,会从本身的缓存中获取,客户端的缓存会定时更新。
当Eureka服务挂了以后,并不会致使客户端找不到须要请求的服务实例。可是当Eureka服务器挂掉以后,原来注册表中的服务发生故障或更新,这是就会出现危险的状况。
Eureka服务器同时也是一个客户端,须要提供serviceUrl来同步注册信息,若是不提供就会在日志中出现大量错误。
Eureka服务器配置eureka.client.registerWithEureka=false,eureka.client.fetchRegistry=false
关闭了Eureka服务器之间的同步信息。为了提升可用性,须要配置多个Eureka服务器,并让它们之间互相同步注册信息,当其中一个挂掉以后,Eureka客户端会自动切换到另外的Eureka服务器。
#
Feign的第一个目标是下降将Denominator统一绑定到HTTP API的复杂性。
能够解决API访问中拼接字符串复杂繁琐的问题。方便快捷的发送Eureka的REST请求。
#
Ribbon是一个基于HTTP和TCP客户端的负载均衡器。提供如下功能
Ribbon能够在经过客户端配置的ribbonServerList服务端列表去轮询访问以达到均衡负载的做用。
与Eureka联合使用,能够扩展成从Eureka注册中心获取服务端列表。
#
避免异常故障蔓延
一个延迟和容错库,在隔离对远程系统,服务和第三方库的访问点,中止级联故障,并在复杂的分布式系统中实现弹性。
Spring Cloud使用了Hystrix来实现断路器的共呢个。经过控制那些访问远程系统、服务、第三方库的节点,从而对延迟和故障提供更强大的容错能力。
Hystrix具有回退机制和断路器隔绝的线程和信号隔离,请求缓存和请求打包,监控和配置等功能
执行如下操做
复杂分布式系统结构中的应用程序具备许多依赖关系,每一个依赖关系在某些时候都将不可避免地失败。若是主机应用程序未与这些外部故障隔离,则会将它们取下
例如:对于依赖于30个服务的应用程序,其中每一个服务的正常运行时间为99.99%,为了不级联错误,其中的0.01能够将其隔离。
能够设置当调用一个服务达到必定的阈值(5秒失败20次)打开断路器。开启断路回滚,阻止级联失败并容许关闭服务一段时间进行愈合。
而且能够监控每一个服务访问的运行状态时间
#
使用Eureka实现了服务注册,Ribbon或Feign实现服务的消费以及均衡负载。Hystrix的断路机制来避免异常故障蔓延
Zuul就是对外提供的一个服务网关。跟Nginx实现一样的功能
经过服务网关统一贯外系统提供REST API的过程当中,除了具有服务路由、负载均衡功能外,还具有了权限控制等功能。
Zuul是从设备和网站到Netflix流应用程序后端的全部请求的拦截。
Zuul使用一系列不一样类型的过滤器,使咱们可以快速灵活地将功能应用于咱们的边缘服务。过滤器能够帮助咱们执行如下功能:
服务路由
经过服务路由的功能,对外提供服务时,只须要经过暴露Zuul中配置的调用地址,就可让调用方统一来访问咱们的服务,而不须要了解具体提供的主机信息。
经过上面配置,全部访问 /api-a-url/** 的访问都映射到 localhost:2222上面
提供两种方式映射
服务过滤
对开放服务还须要一些安全措施来保护客户端只能访问它应该访问到的资源。能够用过滤器来实现对外服务的安全控制
例子:检查请求中是否包含accessToken参数,若是没有就拒绝访问
#
分布式应用程序的分布式开源协调服务。
公开了一组简单的基础原件,分布式应用能够在这些原件之上实现更高级别的服务。
好比同步、配置维护、群集和命名。
设计目标
Zookeeper容许程序经过一个共享的相似于标准文件系统的有组织的分层命名空间分布式处理协调。
Zookeeper的实现提供了一个优质的高性能、高可用,严格的访问顺序。
Zookeeper是很是简单和高效的。由于它的目标就是,做为建设复杂服务的基础,好比同步。zookeeper提供了一套保证,他们包括:
#
Apache Dubbo是一个高性能,轻量级,基于Java的RPC框架。提供三个关键功能,包括基于接口的远程调用,容错和负载平衡,以及自动服务注册和发现。
功能
#
独立的开源自动化服务器,可用于自动执行与构建,测试,交付或部署软件相关的各类任务。
#
重温一下微服务的概念:微服务架构是一种架构模式,提倡将单一应用程序划分红一组小的服务,每一个服务运行在其独立的进程中,服务间采用轻量级的通讯机制互相沟通(一般是基于HTTP协议的RESTful API)。每一个服务都围绕着具体业务进行构建,而且可以被独立的部署到生产环境,类生产环境等。
独立部署和自动化部署不是一个概念。自动化部署相对简单,但独立部署关键和难点在于独立
若是失去了服务独立部署的能力,一个微服务架构的威力将大打折扣。
举一个例子
程序员,开发了一个网上商城。代码Push到Github并经过持续集成(Continuous integration,CI)构建持续交付流水线,最终自动化部署到云端产品环境,供用户访问使用。
随着用户和访问量的增长,需求和功能也愈来愈多。
使用微服务能够将后台部分拆成3个服务,简称ABC。
当对A服务作了一次新的提交以后,A服务的最新版本升级到了1.1 。这个新的版本之外的破坏了A与B之间的契约,错误的调用了B的接口,致使出现了错误。
虽然有完善的UT(单元测试),但UT没法发现服务之间的集成是否被破坏。那么是否能够加集成测试呢?
测试多服务集成的测试统一称做端到端测试(End-to-End tests,简称E2E测试)
当A服务逇新版本破坏了B服务的集成时,E2E测试就会及时诊断出来,并阻止A服务的最新版本想产品环境流动,保证不被破坏。
但添加了E2E测试,解决了服务间集成的验证问题,但也失去了微服务架构的重要特征:服务的独立交付。
假设A服务的修复过程当中,BC服务也提交了代码,可是A服务因E2E测试挂掉的问题还未被修复,因此B和C的新版本也被E2E测试拦下来。此时E2E测试就像是一个亮起红灯的路由,阻塞了全部服务通往产品环境的通道。
因此说,随着集中E2E测试的添加,质量被保证的同时,微服务架构也悄然失去了服务独立交付的能力。
虽然可以在代码库,部署结构上,甚至在组织上进行服务划分,但最后一个交付的E2E测试,让全部的服务又纠缠在一块儿了,服务化拆分形同虚设,最终获得了一个看起来像微服务架构的单体应用。
解决方法也很简单:Inline E2E tests
即并不添加新的集中的Pipeline作E2E测试,而是为每个服务的Pipeline都添加一个相同的E2E测试的Stage,至关于将E2E测试lnline到每一个服务各自的部署流水线中
其实lnline E2E测试还不是最关键的,变化点就是假设A服务有了新的提交,运行到A服务本身Pipeline的E2E测试的时候,此时的E2E测试并非像以前同样获取B和C服务的最新代码库版本作集成验证,而获取当前产品环境上的B和C服务的已部署当前版本作集成验证。
如图所示A服务的版本从1.0升级到1.1,当前产品环境的B和C版本是2.0和3.0。执行A服务Pipeline上的E2E测试时,验证过A和B集成存在问题,测试变红,Pipeline挂掉,从而阻断了A服务的1.1版本部署到产品环境,保证了产品环境不会被1.1版本破坏。
假设A尚未被修复,B也有了新的提交,此时B服务Pipeline上的E2E测试并不获取当前A服务的代码库作集成测试,而是获取产品环境上的当前版本作集成测试。假设B和A之间的集成没有问题,那么B就被成功交付到产品环境里面了。
契约测试也是这两年伴随微服务架构的兴起,常常被说起的一种比较新的测试类型。测试金字塔中,位于E2E和Component Test(单个服务API)之间
简单的理解,契约测试就是一种能够用相似于单元测试的技术验证两个服务之间集成的测试技术。相比于更低层次的单元测试的优点是实现方式上又相似于单元测试,更轻量,跑的更快,覆盖的范围天然能够更广更细
契约测试替换掉E2E测试以后,这个架构也会变得更复杂,目前契约测试的框架也有不少,例如Pact或SpringContracts等。
A服务调用B服务的一个API,称为A和B之间存在一个契约,即B应该提供知足契约要求的API,而A也应该按照这个契约约定的方式来调用B的这个API。
这个过程当中A做为调用方,称之为Consumer端。B做为被调用方,称之为Provider端
若是A和B都履行契约,按照契约定义的约定调用和被调用,就能够认为集成不会有问题。但不管是B修改了API破坏契约,仍是A修改了调用API的方式破坏契约,都会致使契约被破坏,反映到测试上就是契约测试失败。
每一个契约,例如A->B,都会有Consumer端和Provider端生成的两个产出物:分别是a-b.consumer.json.1.1(由Consumer端生成的契约文件,因此版本也是Consumer端A的版本号)和a-b.provider.jar.2.0(由Provider端生成的契约验证测试包)这个jar包其实就是一组测试,输入的是a-b.consumer.json,产出则是测试的结果,也就是契约的验证结果:成功或失败
能够把契约文件当成一把钥匙,测试包当成一把锁。契约测试的执行过程就像是用钥匙试着去开这把锁:若是能够打开,认为这A1.1->B.20的契约是知足的,反之契约就是被破坏了。
契约测试不像E2E测试,是有方向的,因此看到a-b和b-a是两个不一样契约。
只有当A1.1->B.2.0和B2.0->A1.1双向的契约都被验证经过后,才能认为A和B的集成是没有问题的。
假设已经构建了ABC三个服务两两之间的契约测试。此时A服务有了新的提交升级到了1.1版本,如何才能经过契约测试来验证A1.1版本可否交付到产品环境呢?
只要经过A的1.1版本的最新代码,生成全部A做为Consumer端的契约文件(a.b.consumer.json.1.1和a-c.consumer.json.1.1),用两把钥匙去试着开对应的锁。
若是均可以打开,就证实A的新版本做为Consumer端与产品环境的B和C的服务是兼容的。
还要考虑A做为Provider的状况,是经过A的1.1版本的最新diamante生成A版本做为Provider端的契约测试,拿着这两把新锁,去试着用产品环境上的两把钥匙去开。
重点
¥