Spring Cloud

spring Cloud - 图1

1. 服务注册中心

1.1. Eureka

1.1.1. 什么是服务注册与发现? 既Eureka是什么呢?

Eureka采用了CS的设计架构,它采用了Eureka作为服务注册功能的服务器,而系统的其他微服务,使用Eureka的客户端连接到Eureka Server并维持心跳连接,这样系统人员就可以通过Eureka server 来监控整个系统中各个微服务是否正常运行。
在服务注册与发现中,有一个注册中心。当服务器A启动的时候,会把当前自己服务器的信息 比如:服务地址、通讯地址等以别名的方式注册到注册中心。另一方服务器B,以A的别名方式去注册中心获取到实际的服务器通讯地址,然后再实现本地RPC远程调用。
核心思想在于:注册中心,因为使用这个注册中心管理每个服务与服务之间的依赖关系。
在任何的RPC远程框架中,都会有一个注册中心用于存放服务地址(接口地址)等相关信息。
spring Cloud - 图2
Eureka中包含着两个组件:
Eureka Server:提供服务注册服务
各个微服务启动时,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用节点的信息,服务节点的信息可以在界面中看到。
Eureka Client:通过注册中心进行访问
是一个java客户端,用于简化与Eureka Server的交互,客户端同时也具备一个内置的、使用轮询负载算法的负载均衡器。在应用启动后,将会向Eureka Server发送心跳 默认30秒,如果Eureka Server在多个心跳周期内没有接受到某个节点的心跳;EurekaServer将会从服务注册表中移出这个服务节点 默认就是90秒。

1.1.2. Eureka集群原理

spring Cloud - 图3
微服务RPC远程调用服务最核心的是 :
高可用。实现:多台Eureka之间 相互注册。相互守望。

1.1.3. Eureka集群搭建

首先你需要创建多个Eureka server实例 部署到不同的服务器上 之后相互注册,application.yml修改如下:
Eureka7001配置:
spring Cloud - 图4
Eureka7002配置:
spring Cloud - 图5
某种意义上讲 上面是简单的内容,7001注册7002,7002注册7001。这就是相互注册,互相守望的落地实现。
具体业务微服务中 配置如下:
spring Cloud - 图6
配置这东西 写死的 没有原理可寻 记吧。
通过 restTemplate 远程调用时 注意 注入IOC容器的配置类中 加上@LoadBalanced 负载均衡 默认轮询

1.1.4. Discovery服务发现

可以通过接口的方式获取注册进微服务的信息。
spring Cloud - 图7

1.1.5. 自我保护机制

1.2. Zookeeper

1.2.1. 简介(java编写的)

Zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby的一个开源实现。
Zookeeper是以Fast Paxos算法为基础的,Paxos算法存在活锁的问题,当多个proposer交错提交时,有可能互相排斥导致没有一个proposer能提交成功,而Fast Paxos做了一下优化,通过选举产生一个leader 领导者,只有一个leader才能提交proposer。
想要了解zookeeper 首先需要了解Fast Paxos算法。

1.2.2. 运行流程

1、选举Leader;
2、同步数据;
3、选举Leader过程中算法有很多,但要达到的选举标准是一致的;
4、Leader要具有最高的执行ID,类似root权限;
5、集群中大多数的机器得到响应并接受选出的Leader。

1.2.3. 搭建

1.3. Consul

1.3.1. 什么是Consul

Consul是一种服务网络解决方案,是一套开源的分布式服务发现和配置管理系统,由HashiCorp公司用Go语言开发的,提供了微服务系统中的服务智力、配置中心、控制总线功能等功能;这些功能每一个都可以单独使用。
官方文档:https://www.consul.io/docs/intro

1.3.2. Consul的优点是什么?

基于raft协议,比较简洁、支持健康检查、支持http和dns协议、支持跨数据中心的WAN集群、提供图形界面、跨平台等。

1.3.3. Consule具体能干什么呢?

服务发现:提供HTTP和DNS两种发现方式
健康监测:支持多种协议,HTTP、TCP、Docker、Shell脚本定制化
KV存储
多数据中心
可视化Web界面

1.3.4. Consule安装

中文:https://www.springcloud.cc/spring-cloud-consul.html
安装:https://learn.hashicorp.com/tutorials/consul/get-started-install

安装贼简单。

1.4. 三个注册中心异同点

经典的CAP理论:
spring Cloud - 图8
最多同时较好的满足两个:
CAP的核心是:一个分布式系统不可能同时很好的满足一致性、可用性、分区容错这三大需求的,所以 根据CAP理论将Nosql数据库分成了满足CA、CP、AP三大类
CA:单点集群,满足一致性、可用性;但是可扩展性不好。
CP:满足一致性、分区容错性;通常性能不是特别高。
AP:满足可用性、分区容错性;但一致性要求低一点。
spring Cloud - 图9

注:CAP理论关注的粒度是数据 而不是整体系统设计的策略

Eureka:
是AP架构,当网络分区出现后,为了保证可用性,系统B可以返回旧值,保证系统的可用性。违背了一致性C的要求。
spring Cloud - 图10
Zookeeper/Consul:
是CP架构,当网络分区出现后,为了保证一致性,就必须拒绝请求,否则无法保证一致性。违背了可用性A的要求,只满足一致性和分区容错,既CP。
spring Cloud - 图11

总结:
spring Cloud - 图12

2. 服务调用

2.1. Ribbon

2.1.1. Ribbon是什么呢?

全名 Spring Cloud Ribbon 是基于Netflix Ribbon实现的一套客户端负载均衡工具。
简单的说:Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。Ribbon客户端提供了一系列完善的配置项,比如:连接超时、重连等。就是在配置文件中列出 Load Balancer 后面的所有机器,Ribbon会自动的帮助你基于某种规则(如简单轮询、随机连接等)去连接这台机器,我们很容易使用Ribbon实现自定义的负载均衡算法。

2.1.2. 能干嘛?

Ribbon可以进行(Load Balance)负载均衡。
而负载均衡分为两种:
集中式LB:类似nginx、F5,在服务的消费方和提供方之间使用 独立的LB设施,由该设施负责把访问请求通过某种策略转发到服务的提供方。
进程内LB:将LB的逻辑继承到消费方,消费方从服务注册中心获知到所有的可以用地址,然后再自己从地址中选择出一套合适的机器,而Ribbon就是属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到提供方的地址。

2.1.3. Eureka+Ribbon架构

spring Cloud - 图13
Ribbon在工作时候分为两步:
第一步:先选择Eureka Server,它优先选择在同一个区域内负载较少的server。
第二步:再根据用户指定的策略,在从server取到的服务注册列表中选择一个。
Ribbon提供了多种策略,比如:轮询、随机、根据响应时间加权。

2.1.4. 核心组件IRule

IRule根据特定算法从服务列表中选取一个要访问的服务:
spring Cloud - 图14
RoundRobinRule:轮询
RandomRule:随机
RetryRule:先按照轮询,如果获取失败就在特定时间进行重试
WeightedResponseTimeRule:对轮询的扩展,对于响应时间越快的实例选择权重越大。
BestAvailableRule:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务。
AvailabilityFilteringRule:先过滤故障实例,再选择较小的并发量。
ZoneAvoidanceRule:复合判断server所在区域的性能和server的可用性选择服务器。
spring Cloud - 图15

2.1.5. 改变指定IRule

spring Cloud - 图16
MySelfRule一定不要在@CompomontScan可以扫描的包下。
spring Cloud - 图17

2.1.6. 自定义负载均衡算法

略 稍后补充

2.2. OpenFeign

2.2.1. OpenFeign是什么?

Feign是一个声明式的Web服务客户端,让编写web服务客户端变得非常的简单,只需要创建一个接口并在上面添加注解即可。
而OpenFeign是SpringCloud在Feign的基础上支持了SpringMvc的注解,比如@RequestMapping等等。OpenFeign的@FeignClien可以解析SpringMvc的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并且调用服务。这也是两者的区别。

2.2.2. 搭建过程Ribbon+OpenFeign

首先你需要 注册中心 以Eureka为例:
主启动添加@EnableEurekaServer

spring Cloud - 图18
添加Eureka配置:
spring Cloud - 图19
其次 搭建提供者服务:
主启动类添加 EnableDiscoveryClient或EnableEurekaClient注解
spring Cloud - 图20
搭建消费者(重要):
真正用到OpenFeign的地方:
spring Cloud - 图21
OpenFeign自带Ribbon负载均衡 自己集成了分布式调用功能
spring Cloud - 图22
配置文件:
spring Cloud - 图23
主启动类: 几乎所有服务调用都要 注册—>使用
spring Cloud - 图24
接口:
spring Cloud - 图25

调用:
spring Cloud - 图26
OpenFeign 偏向于面向接口开发,保持与消费者接口的一致,本地调用。
spring Cloud - 图27

2.2.3. OpenFeign超时控制

OpenFeign默认等待一秒钟 如果遇到复杂业务执行过长 会报错
spring Cloud - 图28
设置yml
spring Cloud - 图29

2.2.4. 日志打印功能

NONE:默认的 不打印日志。
BASIC:仅记录请求方法、URL、响应状态码及执行时间。
HEADERS:除了BAISC还有请求和响应的头信息。
FULL:除了HEADERS,还有请求和响应的正文及元数据。
开启:
spring Cloud - 图30
spring Cloud - 图31

3. 服务降级

3.1. Hystrix

3.1.1. Hystrix出现的原因

复杂分布式体系架构中的应用程序有数十个依赖关系,每个依赖关系在某些时刻将不可避免的失败。
spring Cloud - 图32
服务雪崩
多个微服务之间的调用,假设服务A调用微服务B和微服务C,微服务B和C又调用其他的微服务,这就是所谓的“扇出”,如果扇出的链路上某个服务的调用响应时间过长或者不可用,对微服务A的调用就会占用越来越多的系统资源,进而引起系统崩溃。所谓的“雪崩效应”。
对于高流量的应用来说,单一的后端依赖可能会导致所有服务器上的所有资源都在几秒钟内饱和,比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张。导致整个系统发生更多的级联故障,这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或者系统。
所以,通常当你发现一个模块下的某个实例失败后,这时候这个模块还能接受流量,然后这个有问题的模块还调用了其他模块,这样就会发生级联故障,或者叫 雪崩。

3.1.2. Hystrix是什么?

Hystrix是一个用于处理分布式系统的延迟和容错的开源库。
在分布式系统里,许多依赖不可避免的会调用失败,比如:超时、异常等。Hystrix为了保证在一个依赖出现问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
“断路器”本身是一个开关装置。当某个服务单元发生故障后,通过断路器的故障检测,向调用方返回一个符合预期的、可处理的备选响应(fallback),而不是长时间的等待或抛出调用方无法处理的异常。这样就保证了服务调用方的线程会被长时间、不必要的占用,从而避免了故障在分布式系统中蔓延,乃至雪崩。

3.1.3. Hystrix到底能干什么

服务降级

服务降级的处理是在客户端完成的,与服务端没有关系
当某个服务熔断或者响应超时等后,服务器将不再调用,此时客户端可以装备一个本地的fallback回调。返回一个缺省值,虽然服务水平下降,但是能用。
通常在程序运行异常、超时、服务被熔断、线程池/信号量打满等会触发服务降级。

服务熔断

熔断机制是应对雪崩效应的一种微服务链路保护机制。
当扇出链路的某个服务不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速的返回“错误”的响应信息。当检测该节点微服务响应正常后,恢复调用链路。默认五秒连续二十次调用失败就会触发熔断机制。

服务限流

。。。。。。

3.1.4. 运行流程


spring Cloud - 图33
1.每次调用创建一个新的HystrixCommand,把依赖调用封装在run()方法中.
2.执行execute()/queue做同步或异步调用.
3.当前调用是否已被缓存,是则直接返回结果,否则进入步骤 4
4.判断熔断器(circuit-breaker)是否打开,如果打开跳到步骤 8,进行降级策略,如果关闭进入步骤 5
5.判断线程池/队列/信号量是否跑满,如果跑满进入降级步骤8,否则继续后续步骤 6
6.调用HystrixCommand的run方法.运行依赖逻辑
6.1. 调用是否出现异常,否:继续,是进入步骤8,
6.2. 调用是否超时,否:返回调用结果,是进入步骤8
7.搜集5、6步骤所有的运行状态(成功, 失败, 拒绝,超时)上报给熔断器,用于统计从而判断熔断器状态
8.getFallback()降级逻辑.四种触发getFallback调用情况(图中步骤8的箭头来源):
返回执行成功结果

3.1.5. 两种资源隔离方式

线程池隔离模式

使用一个线程池来存储当前的请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求堆积入线程池队列。这种方式需要为每个依赖的服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理)。

信号量隔离模式

使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃改类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)。

两种模式区别

spring Cloud - 图34

3.1.6. Hystrix主要配置项

spring Cloud - 图35
spring Cloud - 图36

3.1.7. 使用Hystrix

当我通过jmeter工具模拟十万次访问甚至更多时 出现正常的访问会出现转圈圈,其他接口服务会变慢;这时候代码还很简单 只是输出语句而已 一旦业务复杂起来 转圈圈会更长,这时就需要对服务进行限制了 就是 服务降级:
spring Cloud - 图37


首先想要服务降级操作 需要在启动类添加注解
spring Cloud - 图38
spring Cloud - 图39
执行时间超过三秒钟或者出现异常 都会跳到备选方法中。
而服务降级 不仅仅可以在提供方,消费方也可以做服务降级。
消费方:

spring Cloud - 图40
spring Cloud - 图41
spring Cloud - 图42
spring Cloud - 图43
这样是针对每个方法 会增加代码冗余膨胀,需要配置全局默认的备选方法:
spring Cloud - 图44
全局备选的方法 无参的方法
导致代码混乱 业务类和处理类混在一起
更好的方式 通过Feign配置:
spring Cloud - 图45
spring Cloud - 图46
注意:PaymentCallbackService实现的方法不要在调用方 有@HystrixCommand注解 否择不会执行的。会执行HystrixCammand的备选方法
服务降级 还是有疑问!!
服务熔断
spring Cloud - 图47
当连续访问出错的 跳到备选方法中时 超出配置的百分之60的失败率时会出现断路 这时访问大于0的参数 依然会进入备选方法中 过一会才可以正常访问。

服务降级和服务熔断 更多知识 以后补充,,,,

4. 服务网关

4.1. Gateway

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/

4.1.1. 什么是Gateway

Gateway是在Spring生态系统之上构建的API网关服务,基于spring5、Spring boot2和Project Reactor等技术。
Gateway意在提供一种简单而有效的方式对API进行路由,以及提供一些强大的过滤器功能,例如:熔断、限流、重试等。
官网中的介绍:
spring Cloud - 图48
简而言之:Spring Cloud Gateway 使用的WebFlux中的Reactor-Netty响应式编程组件,底层使用了Netty通讯框架。
关于WebFlux 是什么?这篇文章不错:https://zhuanlan.zhihu.com/p/92460075

4.1.2. 为什么选择Gateway不用zool

zool停止维护了 而且zool1使用阻塞模型 不利于高流量有性能瓶颈,
Zool2出来的太晚了 spring官方没有继承 自己出了Gateway 异步非阻塞模型。
spring Cloud - 图49

4.1.3. Gateway能干嘛?

spring Cloud - 图50

4.1.4. 微服务架构中 网关在那个层次

spring Cloud - 图51

4.1.5. Gateway三大核心概念

Route(路由):路由是构建网关的基本模块,它由ID、目标uri、一系列的断言和过滤器组成。如果断言是true则匹配路由。
Predicate(断言):参考java的java.util.function.Predicate开发人员可以匹配http请求中的所有内容,如果请求和断言相匹配则进行路由。
Filter(过滤):指的是Spring框架中GatewayFilter的实例,可以在请求被路由前或者后 对请求进行修改。
spring Cloud - 图52
spring Cloud - 图53
spring Cloud - 图54

5. 消息总线

5.1. Bus

spring Cloud - 图55

5.1.1. 能干嘛呢?

SpringCloud Bus能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更高,事件推送等,也可以当做微服务间的通信通道。
spring Cloud - 图56

5.1.2. 什么是消息总线

在微服务架构中,通常会使用轻量级的消息代理来构建一个共同的消息主题,并让系统中所有的微服务实例都连接上来,由于该主题中产生的消息会被所有的实例监听和消费,所有被称 消息总线。
基本原理:ConfigClient实例都监听MQ中同一个topic(默认 springCloudBus),当一个服务刷新数据的时候,它会吧这个信息放入到topic中,这样其他监听同一个topic的服务都会得到通知,然后去更新自己的配置。
下载:https://github.com/rabbitmq/rabbitmq-server/releases/tag/v3.7.14
https://www.erlang.org/downloads/21.3
具体安装和操作 请看Rabbtmq篇。

5.1.3. 思路

利用消息总线触发一个服务端ConfigServer的/bus/refresh端点,而刷新所有客户端的配置。
spring Cloud - 图57

5.1.4. 搭建实现

配置中心添加依赖:

  1. <groupId>org.springframework.cloud</groupId>
  2. <artifactId>spring-cloud-starter-bus-amqp</artifactd>


添加订阅主题:
spring Cloud - 图58
接收方:
spring Cloud - 图59
这样就可以手动刷新配置中心 其他接收方 都可以接受。

6. Spring Cloud Alibaba

6.1. Nacos

Naming Configuration Service
https://nacos.io/zh-cn/blog/
一个更易于构建云原生应用的动态服务发现,配置管理和服务管理中心。
Nacos就是注册中心+配置管理的组合。
Nacos=Eureka+config+bus

6.2. 注册中心对比

spring Cloud - 图60

  • 后续再完善吧。