微服务框架学习笔记

微服务框架

微服务

多年以来,咱们一直在寻找更好的方法来构建应用系统。咱们一直在学习已有的技术,尝试新技术,使用不一样的方式来构建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视图

一般是一个庞大的代码库。服务器端的应用逻辑,前端客户端逻辑,后台做业等都在同一个代码库定义。开发人员想要进行更改或更新,须要一次构建和部署整个堆栈

优势: 

  • 更少的跨域问题
  • 减小操做开销:只须要一个应用程序来设置日志记录、监视、测试。部署简单
  • 更容易测试:自动化测试更易于设置和运行
  • 性能:与微服务相比,总体结构还具备性能优点。一般是本地调用而不是网络API调用 

缺点:

  • 紧耦合:总体结构变得更大。服务隔离变得困难,独立扩展和代码维护变得困难
  • 更难理解:与微服务相比,单片应用更难理解。

微服务

微服务架构是指将单个应用程序开发为一套小型服务的概念,而不是将它们开发为一个大型的“总体”

每一个分解的个性化的服务都在本身的进程上运行,与轻量级机制(HTTP)进行通讯。彻底成熟的微服务可独立部署,但必要时能够协同工做

优势:

  • 更好的组织:微服务架构一般组织的更好,由于每一个微服务都有很是特定的工做,不关心其余工做
  • 解耦:更容易重构和从新配置,以知足不一样应用程序的需求
  • 更少的错误

缺点:

  • 每项服务的跨领域关注:构建新的微服务架构时,可能会发现许多在设计时未预料到的跨域问题。须要为每一个交叉问题产生单独模块的开销,或交叉问题封装在全部流量经过的另外一个服务层。
  • 更高的操做开销:微服务常常部署在它们本身的虚拟机或容器上。 

如何选择

考虑几个关键因素,以下

  • 有没有微服务经验
  • 须要基于云的基础架构来使微服务适用于您的项目
  • 评估业务风险

适合使用单片应用

  • 团队规模小,没法解决更普遍和更高效的微服务架构
  • 正在构建未经正式的产品或概念
  • 没有微服务经验:是否能够冒险去学习

适合微服务

  • 须要快速、独立的服务交互
  • 一部分平台须要很是高效:若是企业正在对数PB的日志量进行密集处理,可能但愿用C++构建服务
  • 计划扩展团队:您的团队从一开始就习惯于在不一样小团队中进行开发,而且让团队按服务边界分开,能够轻松地扩展您的开发组织

微服务边界的重要性

使用微服务开发新系统的核心好处之一是该架构容许开发人员独立构建或修改单个组件时,当涉及最小化每一个API之间的回调数量时会出现问题

避免任意规则

设计和建立微服务时,不须要陷入使用任意规则的陷阱。下面的规则,并非肯定微服务边界的正确方法

  • 微服务应该有X行代码:微服务中多少代码行没有限制。关键是确保高内聚性
  • 将每一个功能转变为微服务:实际上取决于功能是什么以及它如何为整个系统服务 

精心设计的服务特色

高内聚,松耦合

高内聚是指一个软件模块是由相关性很强的代码组成

特征1:不与其余服务共享数据库表

若是多个服务引用相同的表,那么在设计微服务时就不适合,由于可能意味着你的数据库是耦合的来源。

开发新服务时使用的主要基本原则之一就是它们不该该跨越数据库边界。每一个服务都应该依赖于本身的一组底层数据存储。这使得咱们能够集中访问控制,审计日志记录,缓存逻辑等

若是数据库表的一个子集与数据集的其他部分没有或不多有链接,那么组件能够呗隔离到一个单独的API或单独的服务中,这是一个强烈信号

每一个服务应该有本身的表和永远不该该共享数据库表

特征2:具备最少许的数据库表

微服务的理想大小应该足够小,每一个数据库表也是同样的。最佳状况是一个或两个数据库表

特征3:考虑有状态和无状态

设计微服务时,须要考虑它是否须要访问数据库,或者它是否处理过TB级别数据的无状态服务。

经过定义服务的输入和输出来定义服务的边界。有时候服务是网络API,但它也多是使用文件并在数据库中生成记录的进程

特征4:考虑数据可用性需求 

设计微服务时,须要记住那些服务将依赖于此新服务,以及在该数据不可用时的整个系统的影响。

考虑到这一点,也能够正确地设计此服务的数据备份和恢复系统

特征5:单一的真实来源 

设计服务时,让其称为系统中某些内容的惟一真实来源。

注意事项 

整个团队能够专门拥有服务,在肯定边界时,组织性就会发挥做用。

还有两个须要考虑的因素:独立的发布计划不一样的正常运行时间 

如何判断服务是否过小或未正肯定义 

第一个指标是服务之间的任何过分依赖,若是两个服务不断地相互呼叫,那么这是一个强烈的耦合指示和一个信号,可能会更好地组成一个服务

第二个,若是设置服务的开销大于使其独立的好处

#

JAVA微服务

框架介绍

使用Java搭建微服务框架语言

未使用微服务框架问题分析:

  1. 数据结构不一致,缺少统一标准
  2. 重复维护:各自进行维护,很难保证信息及时同步
  3. 没法知足多汇报线的需求:一人多岗,一人多汇报线的状况
  4. SOA(面向服务架构)建设过程必不可少的基础服务:SOA架构是企业信息平台化,标准化建设的最佳方案之一。组织机构与人员信息是各业务系统中必不可少的基础组件与核心服务,在企业SOA建设中通常都是放在首要阶段进行建设。
  5. 平台化管理与统一受权的核心功能:实现各业务系统的统一受权,而统一的人员管理是实现这一点的基本要求

统一用户认证平台

统一用户认证平台用于集中管理组织与人员信息,提供统一标准的人员主数据。经过SOA服务总线与各业务系统进行集成,同时为单点登陆提供统一的身份认证信息。

统一用户认证平台与企业邮箱,企业微信息,AD域进行集成。实现一个帐号,全网登陆

技术选择

Spring Framework  基础框架支持

Spring Boot  做为服务的开发框架

Spring Cloud 进行微服务设计与开发

Spring Cloud Netflix 为Spring Boot应用提供Netflix OSS集成

Eureka 做为云服务器中服务注册与发现中心,实现负载均衡

Feign 进行服务访问,简化Eureka访问参数

Ribbon 实现Eureka集群的负载均衡

Hystrix 进行服务容错处理,具有回退机制和断路器功能的线程和信号隔离,请求缓存\打包以及监控和配置

Zuul 做为服务网关

ZooKeeper 实现高度可靠的分布式协调

Dubbo 阿里开源高性能优秀服务框架。

前端
AngularNg-zorro

VueJsElement

部署

Jenkins,GitLab CI 自动化部署

Docker 集装箱部署

系统结构

 

技术点介绍

Spring Framework

为现代基于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 Boot

能够轻松建立独立的,生产级的基于Spring的应用程序。

为Spring平台及第三方库提供开箱即用的设置。多数Spring应用只须要不多的配置。

特征

  • 建立独立的Spring应用程序
  • 直接嵌入Tomcat,Jetty或Undertow(无需部署WAR包)
  • 提供入门依赖项以简化构建配置
  • 尽量自动配置Spring和第三方库
  • 提供生产就绪功能,例如指标、运行情况检查和外部化配置
  • 没有代码生成,也不须要XML配置

#

Spring Cloud

为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁定,领导选举,分布式会话,集群状态)

使用Spring Cloud开发人员能够快速搭建实现这些模式的服务和应用程序。适用于任何分布式环境,包括开发人员本身的笔记本、数据中心和Cloud Foundry等托管平台

特征

Spring Cloud专一于为典型用例提供良好的开箱即用体验,并为其余用户提供可扩展性机制

  • 分布式/版本化配置
  • 服务注册和发现
  • 路由
  • Service到Service Calls
  • 断路器
  • 全局锁
  • Leadership election and cluster state
  • 分布式消息

采用了一种很是具备声明性的方法,一般只须要更改类路径和/或注释便可得到大量内容

主要项目

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:支持无服务器提供商之间的统一编程模型

#

Spring Cloude Netflix

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过滤器的自动注册,以及反向代理建立的配置方法的简单约定

#

Eureka

一种基于REST的服务,用于发现定位服务,以实现中间层服务器的负载平衡和故障转移。将此服务称为Eureka Server。

Eureka还附带了一个基于Java的客户端组件Eureka Client,使与服务的交互变得更加容易。客户端还有一个内置的负载均衡器,能够进行基本的循环负载均衡。在Netflix,一个更复杂的负载均衡器包装Eureka,根据流量,资源使用,错误条件等多种因素提供加权负载平衡,以提供卓越的弹性。

简单的多个服务,经过API调用会面临如下几个问题

  • api是写死的,当调用api地址改变时,其余程序也须要跟着改变
  • 服务的伸缩性比较差,对单个服务的依赖性较强
  • 每次新建一个服务都要配置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

Feign的第一个目标是下降将Denominator统一绑定到HTTP API的复杂性。

能够解决API访问中拼接字符串复杂繁琐的问题。方便快捷的发送Eureka的REST请求。

#

Ribbon

Ribbon是一个基于HTTP和TCP客户端的负载均衡器。提供如下功能

  • 负载均衡
  • 容错
  • 异步和反应模型中的多协议支持(HTTP,TCP,UDP)
  • 缓存和批处理

Ribbon能够在经过客户端配置的ribbonServerList服务端列表去轮询访问以达到均衡负载的做用。

与Eureka联合使用,能够扩展成从Eureka注册中心获取服务端列表。

#

Hystrix

避免异常故障蔓延

一个延迟和容错库,在隔离对远程系统,服务和第三方库的访问点,中止级联故障,并在复杂的分布式系统中实现弹性。

Spring Cloud使用了Hystrix来实现断路器的共呢个。经过控制那些访问远程系统、服务、第三方库的节点,从而对延迟和故障提供更强大的容错能力。

Hystrix具有回退机制和断路器隔绝的线程和信号隔离,请求缓存和请求打包,监控和配置等功能

执行如下操做

  • 经过第三方客户端访问依赖关系,防止和控制延迟和故障
  • 复杂的分布式系统中中止级联故障
  • 快速失败并迅速恢复
  • 优雅降级
  • 实时监控,警报和操做控制

复杂分布式系统结构中的应用程序具备许多依赖关系,每一个依赖关系在某些时候都将不可避免地失败。若是主机应用程序未与这些外部故障隔离,则会将它们取下

例如:对于依赖于30个服务的应用程序,其中每一个服务的正常运行时间为99.99%,为了不级联错误,其中的0.01能够将其隔离。

能够设置当调用一个服务达到必定的阈值(5秒失败20次)打开断路器。开启断路回滚,阻止级联失败并容许关闭服务一段时间进行愈合。

而且能够监控每一个服务访问的运行状态时间

#

Zuul(服务网关)

使用Eureka实现了服务注册,Ribbon或Feign实现服务的消费以及均衡负载。Hystrix的断路机制来避免异常故障蔓延

Zuul就是对外提供的一个服务网关。跟Nginx实现一样的功能

经过服务网关统一贯外系统提供REST API的过程当中,除了具有服务路由、负载均衡功能外,还具有了权限控制等功能。

Zuul是从设备和网站到Netflix流应用程序后端的全部请求的拦截。

Zuul使用一系列不一样类型的过滤器,使咱们可以快速灵活地将功能应用于咱们的边缘服务。过滤器能够帮助咱们执行如下功能:

  • 身份验证和安全性:识别每一个资源的身份验证要求并拒毫不知足这些要求的请求
  • 洞察和监控:边缘跟踪有意义的数据和统计数据,以便为咱们提供准确的生产视图
  • 动态路由:根据须要动态地将请求路由到不一样的后端群集
  • 压力测试:逐渐增长群集的流量以衡量性能
  • Load Shedding:为每种类型的请求分配容量并删除超过限制的请求
  • 静态响应处理:直接在边缘构建一些响应,而不是将它们转发到内部集群
  • 多区域弹性:跨AWS区域路由请求,以使咱们的ELB使用多样化,并使咱们的优点更接近咱们的成员

服务路由

经过服务路由的功能,对外提供服务时,只须要经过暴露Zuul中配置的调用地址,就可让调用方统一来访问咱们的服务,而不须要了解具体提供的主机信息。

经过上面配置,全部访问 /api-a-url/** 的访问都映射到 localhost:2222上面

提供两种方式映射

  • url映射,上图方式
  • serviceId映射,结合Eureka。

 

服务过滤

对开放服务还须要一些安全措施来保护客户端只能访问它应该访问到的资源。能够用过滤器来实现对外服务的安全控制

例子:检查请求中是否包含accessToken参数,若是没有就拒绝访问

#

ZooKeeper

分布式应用程序的分布式开源协调服务。

公开了一组简单的基础原件,分布式应用能够在这些原件之上实现更高级别的服务。

好比同步、配置维护、群集和命名。

设计目标

Zookeeper容许程序经过一个共享的相似于标准文件系统的有组织的分层命名空间分布式处理协调。

Zookeeper的实现提供了一个优质的高性能、高可用,严格的访问顺序。

Zookeeper是很是简单和高效的。由于它的目标就是,做为建设复杂服务的基础,好比同步。zookeeper提供了一套保证,他们包括:

  • 顺序一致性 - 来自客户端的更新会按顺序应用。
  • 原子性 - 更新成功或者失败,没有局部的结果产生。
  • 惟一系统映像 - 一个客户端无论链接到哪一个服务端都会看到一样的视图。
  • 可靠性- 一旦一个更新被应用,它将从更新的时间开始一直保持到一个客户端重写更新。
  • 时效性 - 系统中的客户端视图在特定的时间点保证成为是最新的。

#

Dubbo

Apache Dubbo是一个高性能,轻量级,基于Java的RPC框架。提供三个关键功能,包括基于接口的远程调用,容错和负载平衡,以及自动服务注册和发现。

功能

  • 基于透明接口的RPC:提供基于RPC的高性能接口,对用户透明。(RPC:远程过程调用协议)
  • 智能负载均衡:支持多种开箱即用的负载均衡策略,能够感知下游服务状态,从而减小整体延迟并挺高系统吞吐量
  • 自动服务注册和发现:支持多个服务注册表,能够当即在线/离线检测服务
  • 可扩展性高:Dubbo的微内核和插件设计确保能够经过协议,传输和序列化等核心功能轻松扩展第三方实施
  • 运行时流量路由:能够在运行时配置Dubbo,以便根据不一样的规则路由流量,能够轻松支持蓝绿色部署,数据中心感知路由等功能
  • 可视化的服务治理:为服务治理和维护提供了丰富的工具,例如查询服务元数据,健康状态和统计数据

#

Jenkins

独立的开源自动化服务器,可用于自动执行与构建,测试,交付或部署软件相关的各类任务。

#

Spring集成架构

  • Azure
    • Azure Support:Azure服务的自动配置(服务总线、存储、活动目录、cosmos DB、密钥库等)
    • Azure Active Directory:Spring Security与Azure Active Directory集成以进行身份​​验证
    • Azure Key Vault:Spring值注释与Azure Key Vault Secrets的集成
    • Azure Storage:Azure存储服务集成
  • Cloud AWS
    • AWS Core:来自spring-cloud-aws的本地服务
    • AWS JDBC:AWS上的关系数据库与RDS和spring-cloud-aws-jdbc
    • AWS Messaging:使用SQS和spring-cloud-aws-messaging在AWS上进行消息传递
  • Cloud Circuit Breaker:断路器
    • Hystrix:断路器与spring-cloud-netflix Hystrix
    • Hystrix Dashboard:带有spring-cloud-netflix Hystrix的断路器仪表板
    • Turbine:使用spring-cloud-netflix与Turbine和服务器发送事件的断路器度量聚合
    • Turbine Stream:使用spring-cloud-netflix与Turbine和Spring Cloud Stream进行断路器度量聚合(须要绑定器,例如Kafka或RabbitMQ)
  • Cloud Config:配置
    • Config Client:spring-cloud-config客户端
    • Config Server:经过git或svn后端进行配置的集中管理
    • Vault Configuration:使用HashiCorp Vault进行配置管理
    • Zookeeper Configuration:使用Zookeeper和spring-cloud-zookeeper-config进行配置管理
    • Consul Configuration:Hashicorp Consul的配置管理
  • Cloud Contract:合同
    • Cloud Contract Verifier:测试自动生成测试所需的依赖关系 
    • Cloud Contract Stub Runner:用于基于HTTP /消息传递的通讯的Stub Runner。容许从RestDocs测试建立WireMock存根
  • Cloud Core:核心
    • Cloud Bootstrap:spring-cloud-context(例如Bootstrap context和@RefreshScope)
    • Cloud Function:做为bean的功能
    • Cloud Security:使用spring-cloud-security保护负载平衡和路由
    • Cloud OAuth2:具备spring-cloud-security的OAuth2和分布式应用程序模式
    • Cloud Task:任务结果跟踪和与Spring Batch的集成
  • Cloud Discovery:发现
    • Eureka Discovery:使用spring-cloud-netflix和Eureka进行服务发现
    • Eureka Server:spring-cloud-netflix Eureka Server
    • Zookeeper Discovery:使用Zookeeper和spring-cloud-zookeeper-discovery进行服务发现
    • Cloud Foundry Discovery:使用Cloud Foundry进行服务发现
    • Consul Discovery:Hashicorp Consul的服务发现
  • Cloud Messaging:消息传递
    • Cloud Bus:使用Spring Cloud Stream的简单控制总线(须要绑定器,例如Kafka或RabbitMQ)
    • Cloud Stream:使用Spring Cloud Stream传递微服务(须要绑定器,例如Kafka或RabbitMQ)
    • Reactive Cloud Stream:使用Spring Cloud Stream的反应性消息传递微服务(须要绑定器,例如Kafka或RabbitMQ)
  • Cloud Routing:路由
    • Zuul:使用spring-cloud-netflix Zuul进行智能和可编程路由 
    • Gateway:使用响应式Spring Cloud Gateway进行智能和可编程路由
    • Ribbon:使用spring-cloud-netflix和Ribbon进行客户端负载均衡
    • Feign:使用spring-cloud-netflix Feign的声明式REST客户端
  • Cloud Support:支持
    • Colud Connectors:简化与云平台服务的链接,包括spring-cloud-connector和spring-cloud-cloudfoundry-connector
    • Open Service Broker:建立符合Open Service Broker API规范的服务代理
  • Cloud Tracing:跟踪
    • Sleuth:使用spring-cloud-sleuth经过日志进行分布式跟踪
    • Zipkin Client:使用现有的Zipkin安装和spring-cloud-sleuth-zipkin进行分布式跟踪
  • Core
    • DevTools:Spring Boot开发工具
    • Security:经过spring-security保护您的应用程序
    • Lombok:Java注释库,有助于更快地减小样板代码和代码
    • Configuration Processor:为您的自定义配置键生成元数据
    • Session:用于管理用户会话信息的API和实现
    • Cache:Spring的Cache抽象
    • Validation:JSR-303验证基础设施(已包含在Web中)
    • Retry:经过spring-retry提供声明性重试支持
    • Aspects:使用Spring AOP和AspectJ建立本身的Aspects
  • I/O
    • Batch: Spring Batch支持 
    • Mail:使用Java Mail和Spring Framework的JavaMailSender发送电子邮件
    • Apache Camel:使用Apache Camel进行集成
    • LDAP:LDAP支持,包括spring-data-ldap
    • Quartz Scheduler:使用Quartz安排工做
    • Spring Shell:构建基于shell的客户端
    • Statemachine:使用状态机概念构建应用程序
  • Integration:集成
    • Spring Integration:常见的弹簧集成模块
    • RabbitMQ:经过spring-rabbit的高级消息队列协议
    • Kafka:使用Spring Kafka的Kafka消息支持
    • Kakka Streams:支持使用Apache Kafka Streams构建流处理应用程序
    • JMS(ActiveMQ):经过Apache ActiveMQ的Java消息服务API
    • JMS(Artemis):经过Apache Artemis的Java消息服务API
  • NoSQL
    • Redis:Redis键值数据存储,包括spring-data-redis
    • Reactive Redis:Redis键值数据存储,包括spring-data-redis
    • MongoDB:MongoDB NoSQL数据库,包括spring-data-mongodb
    • Reactive MongoDB:MongoDB NoSQL数据库,包括spring-data-mongodb和被动驱动程序
    • Embedded MongoDB:嵌入式MongoDB进行测试
    • Elasticasearch:Elasticsearch搜索和分析引擎包括spring-data-elasticsearch
    • Solr:Apache Solr搜索平台,包括spring-data-solr
    • Cassandra:Cassandra NoSQL数据库,包括spring-data-cassandra
    • Reactive Cassandra:Cassandra NoSQL数据库,包括spring-data-cassandra和反应式驱动程序
    • Couchbase:Couchbase NoSQL数据库,包括spring-data-couchbase
    • Reactive Couchbase:Couchbase NoSQL数据库,包括spring-data-couchbase和被动驱动程序
    • Neo4j:Neo4j NoSQL图形数据库,包括spring-data-neo4j
  • Ops
    • Actuator:生产就绪功能可帮助您监控和管理您的应用程序
    • Spring Boot Admin(Server):用于Spring引导应用程序的管理界面
    • Spring Boot Admin(Client):使用Spring引导管理实例注册应用程序
  • Pivotal Cloud Foundry:关键的云计算
    • Config Client:在Pivotal Cloud Foundry上配置客户端
    • Service Registry:Pivotal Cloud Foundry上的Eureka服务发现
    • Circuit Breaker:Pivotal Cloud Foundry上的Hystrix断路器
  • SQL
    • JPA:Java持久化API包括spring-data-jpa、spring-orm和Hibernate
    • MySql:MySQL JDBC驱动程序
    • H2:H2数据库(支持嵌入式)
    • JDBC:JDBC数据库
    • MyBatis:使用MyBatis的持久性支持
    • PostgreSQL:PostgreSQL JDBC驱动程序
    • SQL Server:Microsoft SQL Server JDBC驱动程序
    • HSQLDB:HSQLDB数据库(支持嵌入式)
    • Apache Derby:Apache Derby数据库(支持嵌入式)
    • Liquibase:Liquibase数据库迁移库
    • Flyway:Flyway数据库迁移库
    • JOOQ:持久性支持使用面向Java对象的查询
  • Spring Cloud GCP
    • GCP Support:支持Google Cloud Platform服务
    • GCP Messaging:发布并订阅Google Cloud Pub / Sub主题
    • GCP Storage:访问Google云端存储对象
  • Template Engines
    • Thymeleaf:Thymeleaf模板引擎
    • Freemarker:FreeMarker模板引擎
    • Mustache:Mustache模板引擎
    • Groovy Templates:Groovy模板引擎
  • Web
    • Web:使用Tomcat和Spring MVC进行全堆栈web开发
    • Reactive Web:使用Netty和Spring WebFlux进行响应式web开发
    • Rest Repositories:经过Spring-Data-REST-webmvc在REST上公开Spring数据存储库
    • Rest Repositories HAL Browser:在浏览器中浏览Spring Data REST存储库
    • HATEOAS:HATEOAS-based RESTful服务
    • Web Services:使用Spring Web服务开发契约优先的SOAP服务
    • Jersey(JAX-RS):支持JAX-RS的RESTful Web服务框架
    • Websocket:Websocket开发与SockJS和STOMP
    • REST Docs:经过结合手写文档和自动生成文档来记录RESTful服务
    • Vaadin:java web应用程序框架

微服务敢独立交付吗?

重温一下微服务的概念:微服务架构是一种架构模式,提倡将单一应用程序划分红一组小的服务,每一个服务运行在其独立的进程中,服务间采用轻量级的通讯机制互相沟通(一般是基于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的集成是没有问题的。

用契约测试代替E2E

假设已经构建了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端的契约测试,拿着这两把新锁,去试着用产品环境上的两把钥匙去开。

重点

  • 微服务架构下的独立部署(交付)很重要,但每每容易被忽视,没有被引发足够重视。
  • 为了实现微服务的独立持续交付,咱们要向“后”看,不要向“前”看,即关注当前变动服务与部署环境中其余服务的兼容性而不是关注当前变动服务与其余服务最新版本的兼容性。
  • 用契约测试来替代E2E测试,下降测试成本,提升测试覆盖,尽早测试。并经过不断地完善契约管理,保障微服务架构质量和避免微服务架构腐化僵化。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相关文章
相关标签/搜索