(最高版本)spring cloud

177 阅读11分钟

各组件的实现原理:

zuul网关:

所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能

网关的作用: 统一入口;减少客户端与服务端的耦合;权限校验,请求转发、监控、负载均衡、缓存、静态响应处理,如果服务出现异常,可以返回默认值,或直接抛出异常,或取缓存值;Zuul网关的限流保护

优点:可以为客户端定制api,根据api调用多个微服务,返回请求值。

使用

@EnableZuulProxy开启网关

Zuul网关过滤器

前置过滤器:在请求进入zuul后,立即执行的过滤逻辑

路由后过滤:请求进入zuul后,并zuul执行了请求路由后,执行的过滤逻辑

后置过滤:远程服务调用后,执行的过滤逻辑

异常过滤:任意一个过滤失败,远程调用失败,调用超时后,执行的过滤

zuul的父类提供的抽象方法

filterType:方法返回字符串数据,代表当前过滤器的类型。可选值有-pre, route, post, error。

filterOrder:返回int数据 执行的权限

shouldFilter:返回boolean数据,代表当前filter是否生效。

run:具体的过滤执行逻辑

执行流程

Zuul网关的容错

Zuul中的服务降级处理

网关的实现原理

ribbon(轮询)+hytrx(熔断)+filter(过滤器)

zuul2.0: 使用netty server作为网关监听服务器监听客户端发来的请求,然后把请求转发到前置过滤器(inbound filters)进行处理,处理完毕后在把请求使用netty client代理到具体的后端服务器进行处理,处理完毕后在把结果交给后者过滤器(outbound filters)进行处理,然后把处理结果通过nettyServer写回客户端。

Hystrix

Hystrix容错

资源隔离

Hystrix设计目标:

1、对来自依赖的延迟和故障进行保护

2、防止故障的连锁反应

3、快速失败,尽快恢复

4、回退并优雅降级

5、提供近实时的监控与告警

设计的原则

1、防止单独的依赖耗尽资源

2、过载立即切断,防止失败

3、尽可能提供回退以保护用户免受故障

4、使用隔离技术(例如隔板,泳道和断路器模式)来限制任何一个依赖的影响

5、通过近实时的指标,监控和确保故障被即使发现

6、近实时地监控指标和配置的修改。

Hystrix处理流程

Hystrix整个工作流如下:

1、封装好请求

2、根据条件有以下4种执行方式:

a、判断是否使用缓存响应请求,如果是,开启,直接响应缓存

b、判断熔断器是否打开,如果打开,走Fallback备用逻辑

c、判断线程池/队列/信号量是否已满,已满则走Fallback备用逻辑

d.调用依赖服务,如果执行失败或者超时,走Fallback备用逻辑,否则返回请求响应

3、统计熔断器监控指标;返回请求响应

Hystrix容错

Hystrix的容错主要是通过添加容许延迟和容错方法,帮助控制这些分布式服务之间的交互。 还通过隔离服务之间的访问点,阻止它们之间的级联故障

资源隔离

线程隔离-线程池

通过将发送请求线程与执行请求的线程分离,可有效防止发生级联故障。当线程池或请求队列饱和时,Hystrix将拒绝服务,使得请求线程可以快速失败,从而避免依赖问题扩散。

线程池模式下,当超过指定时间未响应的服务,Hystrix会通过响应中断的方式通知线程立即结束并返回。

线程隔离的接收线程和请求线程是分开的,每个服务一个线程池,这样的缺点就是计算开销大,需要排队,调度,上下文切换;

线程隔离-信号量

当依赖延迟极低的服务时,线程池隔离技术引入的开销超过了它所带来的好处。这时候可以使用信号量隔离技术来代替,通过设置信号量来限制对任何给定依赖的并发调用量

由于Hystrix默认使用线程池做线程隔离

但是信号量不支持异步,也不支持超时,也就是说当所请求的服务不可用时,信号量会控制超过限制的请求立即返回,但是已经持有信号量的线程只能等待服务响应或从超时中返回,即可能出现长时间等待

熔断器简介

第一步,调用allowRequest()判断是否允许将请求提交到线程池

如果熔断器强制打开,circuitBreaker.forceOpen为true,不允许放行,返回。 如果熔断器强制关闭,circuitBreaker.forceClosed为true,允许放行。此外不必关注熔断器实际状态,也就是说熔断器仍然会维护统计数据和开关状态,只是不生效而已。 第二步,调用isOpen()判断熔断器开关是否打开

如果熔断器开关打开,进入第三步,否则继续; 如果一个周期内总的请求数小于circuitBreaker.requestVolumeThreshold的值,允许请求放行,否则继续; 如果一个周期内错误率小于circuitBreaker.errorThresholdPercentage的值,允许请求放行。否则,打开熔断器开关,进入第三步。 第三步,调用allowSingleTest()判断是否允许单个请求通行,检查依赖服务是否恢复

如果熔断器打开,且距离熔断器打开的时间或上一次试探请求放行的时间超过circuitBreaker.sleepWindowInMilliseconds的值时,熔断器器进入半开状态,允许放行一个试探请求;否则,不允许放行。

回退降级

降级,通常指务高峰期,为了保证核心服务正常运行,需要停掉一些不太重要的业务,或者某些服务不可用时,执行备用逻辑从故障服务中快速失败或快速返回,以保障主体业务不受影响。Hystrix提供的降级主要是为了容错,保证当前服务不受依赖服务故障的影响,从而提高服务的健壮性。要支持回退或降级处理

Hystrix在以下几种情况下会走降级逻辑:

执行construct()或run()抛出异常 熔断器打开导致命令短路 命令的线程池和队列或信号量的容量超额,命令被拒绝 命令执行超时

降级回退方式

Fail Fast 快速失败

快速失败是最普通的命令执行方法,命令没有重写降级逻辑。 如果命令执行发生任何类型的故障,它将直接抛出异常。

Fail Silent 无声失败

指在降级方法中通过返回null,空Map,空List或其他类似的响应来完成。

Fallback: Static

指在降级方法中返回静态默认值。 这不会导致服务以“无声失败”的方式被删除,而是导致默认行为发生。如:应用根据命令执行返回true / false执行相应逻辑,但命令执行失败,则默认为true

Fallback: Stubbed

当命令返回一个包含多个字段的复合对象时,适合以Stubbed 的方式回退。

Fallback: Cache via Network

有时,如果调用依赖服务失败,可以从缓存服务(如redis)中查询旧数据版本。由于又会发起远程调用,所以建议重新封装一个Command,使用不同的ThreadPoolKey,与主线程池进行隔离。

feign的执行流程

1、基于面向接口的动态代理生成实现类(动态创建实例,会根据注解的不同,解析不同的处理器methodhandler)

2、基于requestbean,动态生成request(根据传入的Bean对象和注解信息,从中提取出相应的值,来构造Http Request 对象)

3、使用encoder将bean生成http报文正文

Feign 最终会将请求转换成Http 消息发送出去,传入的请求对象最终会解析成消息体,如下所示:

4、拦截器负责对请求和返回处理

拦截器负责对请求和返回进行装饰处理 在请求转换的过程中,Feign 抽象出来了拦截器接口,用于用户自定义对请求的操作,比如,如果希望Http消息传递过程中被压缩,可以定义一个请求拦截器。

5、发送http请求

Feign 内置了一个重试器,当HTTP请求出现IO异常时,Feign会有一个最大尝试次数发送请求

Feign 真正发送HTTP请求是委托给 feign.Client 来做的。

Feign 默认底层通过JDK 的 java.net.HttpURLConnection 实现了feign.Client接口类,在每次发送请求的时候,都会创建新的HttpURLConnection 链接,这也就是为什么默认情况下Feign的性能很差的原因。可以通过拓展该接口,使用Apache HttpClient 或者OkHttp3等基于连接池的高性能Http客户端。

Feign 整体框架非常小巧,在处理请求转换和消息解析的过程中,基本上没什么时间消耗。真正影响性能的,是处理Http请求的环节。

HttpURLConnection是JDK自带的HTTP客户端技术,并不支持连接池,如果要实现连接池的机制,还需要自己来管理连接对象。对于网络请求这种底层相对复杂的操作,如果有可用的其他方案,也没有必要自己去管理连接对象。 Apache提供的HttpClient框架相比传统JDK自带的HttpURLConnection,它封装了访问http的请求头,参数,内容体,响应等等;它不仅使客户端发送HTTP请求变得容易,而且也方便了开发人员测试接口(基于Http协议的),即提高了开发的效率,也方便提高代码的健壮性;另外高并发大量的请求网络的时候,还是用“HTTP连接池”提升吞吐量。 OKHttp是一个处理网络请求的开源项目,是安卓端最火热的轻量级框架。OKHttp拥有共享Socket,减少对服务器的请求次数,通过连接池,减少了请求延迟等技术特点。

优化:

1、使用Gzip压缩发送的数据

2、替换为httpclient客户端(使用http连接池提供性能)

Eureka简介:

ribbon

SpringCloud Config

feign 和 openfeign

Eureka的使用: 服务端搭建: 1.maven导入(其他几个是必要的包) 2.yml文件配置(单机版) 图片说明: port:访问的端口 hostname:实例名称 主启动类配置: 客户端搭建: maven导入: yml文件编辑 客户端1(消费者) 客户端2(提供者) 主启动类配置

集群搭建: maven不变; yml各服务互相访问; 客户端的yml,每个节点都访问 在resttemplate 的类中,配置@loadBalanced resttemplate使用的url换成生产者在eureka上显示的名称,也就是yml上配置的实例名 配置客户端在erueka上显示的别名 服务发现的配置(为了用户可以通过访问生产者,可以看到生产者都有哪些服务可以被调用) CAP理论 zookeeper和consul

ribbon:提供客户端的软件负载均衡算法和服务调用 ribbon本地负载均衡,在调用服务接口的时候,会在注册中心获取注册的信息,缓存在本地的jvm,从而在本地实现rpc远程调用。 可以通过resttemplate或者Feign,openFeign访问。 ribbon的使用,在客户端的resttemplate配置中加上注解(不用导maven,因为在eureka中已经包含ribbon的包) 没有ribbon的时候,客户端消费者是直接向生产者发请求,有ribbon后,消费者通过ribbon,让ribbon向生产者发送请求 ribbon存在的负载均衡策略: 配置个性化的负载均衡策略:

服务降级

hystrx的服务熔断,降级和限流 降级:返回有友好的提示:使用场景:超时,程序异常,服务熔断导致降级,线程池,信号量打满 熔断,拒绝访问,返回友好提示 限流:限制访问数数量 熔断器在消费端和服务端都可以使用,一般是用在消费端