springcloud组件知识
一、Spring Cloud基础知识
微服务架构
微服务架构可以说是SOA架构的⼀种拓展,这种架构模式下它拆分粒度更⼩、服务更独⽴。把应⽤拆分成为⼀个个微⼩的服务,不同的服务可以使⽤不同的开发语⾔和存储,服务之间往往通过Restful等轻量级通信。微服务架构关键在于微⼩、独⽴、轻量级通信。微服务是在SOA上做的升华粒度更加细致,微服务架构强调的⼀个重点是“业务需要彻底的组件化和服务化。
微服务架构的优点
1)微服务很⼩,便于特定业务功能的聚焦 A B C D
2)微服务很⼩,每个微服务都可以被⼀个⼩团队单独实施(开发、测试、部署上线、运维),团队合作⼀定程度解耦,便于实施敏捷开发
3)微服务很⼩,便于重⽤和模块之间的组装
4)微服务很独⽴,那么不同的微服务可以使⽤不同的语⾔开发,松耦合
5)微服务架构下,我们更容易引⼊新技术
6)微服务架构下,我们可以更好的实现DevOps开发运维⼀体化;
微服务架构的缺点
1)微服务架构下,分布式复杂难以管理,当服务数量增加,管理将越加复杂;
2)微服务架构下,分布式链路跟踪难等;
微服务架构的概念
服务注册:服务提供者将所提供服务的信息(服务器IP和端⼝、服务访问协议等) 注册/登记到注册中⼼
服务发现:服务消费者能够从注册中⼼获取到较为实时的服务列表,然后根究⼀定 的策略选择⼀个服务访问
负载均衡:负载均衡即将请求压⼒分配到多个服务器(应⽤服务器、数据库服务器等),以 此来提⾼服务的性能、可靠性。
熔断:熔断即断路保护。微服务架构中,如果下游服务因访问压⼒过⼤⽽响应变慢或失 败,上游服务为了保护系统整体可⽤性,可以暂时切断对下游服务的调⽤。这种牺 牲局部,保全整体的措施就叫做熔断。
链路追踪:所谓链路追踪,就是对⼀次请求涉及的很多个服务链路进⾏⽇志记 录、性能监控。
API ⽹关:微服务架构下,不同的微服务往往会有不同的访问地址,客户端可能需要调⽤多个服务的接⼝才能完成⼀个业务需求,API请求调用统⼀接⼊API⽹关层,由⽹关转发请求。API⽹关更专注在安全、路由、流量等问题的处理上。
1) 统⼀接⼊(路由)
2) 安全防护
3) ⿊⽩名单
4) 协议适配
5) 流量管控
6) 容错能⼒
体系结构
Spring Cloud中的各组件协同⼯作,才能够⽀持⼀个完整的微服务架构。
1) 注册中⼼负责服务的注册与发现,很好将各服务连接起来
2) API⽹关负责转发所有外来的请求
3) 断路器负责监控服务之间的调⽤情况,连续多次失败进⾏熔断保护。
4) 配置中⼼提供了统⼀的配置信息管理服务,可以实时的通知各个服务获取最新的 配置信息
Spring Cloud 与 Dubbo
Dubbo是阿⾥巴巴公司开源的⼀个⾼性能优秀的服务框架,基于RPC调⽤,对于⽬前使⽤率较⾼的Spring Cloud Netflix来说,它是基于HTTP的,所以效率上没有Dubbo⾼,但问题在于Dubbo体系的组件不全,不能够提供⼀站式解决⽅案。
Spring Cloud 与 Spring Boot
Spring Cloud 只是利⽤了Spring Boot 的特点,让我们能够快速的实现微服务组件开发,否则不使⽤Spring Boot的话,我们在使⽤Spring Cloud时,每⼀个组件的相关Jar包都需要我们⾃⼰导⼊配置以及需要开发⼈员考虑兼容性等各种情况。所以Spring Boot是我们快速把Spring Cloud微服务技术应⽤起来的⼀种⽅式
二、Spring Cloud核心组件
Eureka注册服务中心
分布式微服务架构中,服务注册中⼼⽤于存储服务提供者地址信息、服务发布相关的属性信息,消费者通过主动查询和被动通知的⽅式获取服务提供者的地址信息,⽽不再需要通过硬编码⽅式得到提供者的地址信息。
1) 服务提供者启动
2) 服务提供者将相关信息主动注册到注册中心
3) 服务消费者获取服务注册信息:
Pull模式:服务消费者可以主动拉去可用的服务提供者清单
Push模式:服务消费者可以主动拉去可用的服务提供者清单
4) 服务消费者直接调用服务提供者
主流服务中心对比
Zookeeper: Zookeeper ⽤来做服务注册中⼼,主要是因为它具有节点变更通知功能,只要客户端监听相关服务节点,服务节点的所有变更,都能及时的通知到监听客户端,这样作为调⽤⽅只要使⽤ Zookeeper 的客户端就能实现服务节点的订阅和 变更通知功能了,zookeeper遵循半数集群可用原则。
Nocas: 注册中⼼ + 配置中⼼的组合,帮助我们解决微服务开发必会涉及到的服务注册与发现,服务配置,服务管理等问题。Nacos 是Spring Cloud Alibaba 核⼼组件之⼀,负责服务注册与发现,还有配置。
基础架构
Eureka 包含两个组件:Eureka Server 和 Eureka Client,也就是服务端,存储该服务的信息以及客户端
1)图中us-east-1c、us-east-1d,us-east-1e代表不同的区也就是不同的机房
2)图中每⼀个Eureka Server都是⼀个集群。
3)图中Application Service作为服务提供者向Eureka Server中注册服务, Eureka Server接受到注册事件会在集群和分区中进⾏数据同步,Application Client作为消费端(服务消费者)可以从Eureka Server中获取到服务注册信息,进⾏服务调⽤。
4)微服务启动后,会周期性地向Eureka Server发送⼼跳(默认周期为30秒) 以续约⾃⼰的信息
5)Eureka Server在⼀定时间内没有接收到某个微服务节点的⼼跳,Eureka Server将会注销该微服务节点(默认90秒)
6)每个Eureka Server同时也是Eureka Client,多个Eureka Server之间通过复制的⽅式完成服务注册列表的同步 7)Eureka Client会缓存Eureka Server中的信息。即使所有的Eureka Server节点都宕掉,服务消费者依然可以使⽤缓存中的信息找到服务提供者
Euraka客户端详解
服务提供者(也是Eureka客户端)要向EurekaServer注册服务,并完成服务续约等工作
服务注册详解:导⼊了eureka-client依赖坐标,配置Eureka服务注册中⼼地址后,服务在启动时会向注册中⼼发起注册请求,携带服务元数据信息,Eureka注册中⼼接收到了之后会把服务的信息保存在Map中。
服务续约详解:服务每隔30秒会向注册中⼼续约(⼼跳)⼀次(也称为报活),如果没有续约,租约在90秒后到期,然后服务会被失效。
获取服务列表详解:服务消费者启动时,从 EurekaServer服务列表获取只读备份,缓存到本地,每隔30秒,会重新获取并更新数据。
Eurake服务端详解
服务下线:当服务正常关闭操作时,会发送服务下线的REST请求给EurekaServer,服务中⼼接受到请求后,将该服务置为下线状态。
失效剔除:Eureka Server会定时,默认60S检查发现实例在在⼀定时间,默认90S没有收到心跳,注销此实例。
自我保护:如果在15分钟内超过85%的客户端节点都没有正常的⼼跳,那么Eureka就认为客户端与注册中⼼出现了⽹络故障,Eureka Server⾃动进⼊⾃我保护机制。
1) 不会剔除任何服务实例,保证大多数服务可用
2) Eureka Server仍然能够接受新服务的注册和查询请求,但是不会同步,需要等网络稳定再同步。
3) 可配置开关:eureka.server.enable-self-preservation
Ribbon负载均衡
负载均衡分为服务器端负载均衡和客户端负载均衡
服务器端负载均衡:Nginx、F5等等,请求到达服务器之后由这些负载均衡器根据⼀定的算法将请求路由到⽬标服务器处理。
客户端负载均衡:Ribbon,服务消费者客户端会有⼀个服务器地址列表,调用⽅在请求前通过⼀定的负载均衡算法选择⼀个服务器进⾏访问,负载均衡算法的执行是在请求客户端进⾏。
负载均衡策略,定义在IRule接口
Ribbon工作原理
Ribbon给restTemplate添加了⼀个拦截器interceptor方法,通过拦截器进行请求拦截,然后通过负载策略实现请求分发。
Hystrix熔断器
雪崩效应
扇⼊:代表着该微服务被调⽤的次数,扇⼊⼤,说明该模块复⽤性好
扇出:该微服务调⽤其他微服务的个数,扇出⼤,说明业务逻辑复杂
在微服务架构中,⼀个应用可能会有多个微服务组成,微服务之间的数据交互通过远程过程调⽤完成。这就带来⼀个问题,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务,这就是所谓的“扇出”。如果扇出的链路上某个微服务的调用响应时间过⻓或者不可⽤,对微服务A的调用就会占⽤越来越多的系统资源,进⽽引起系统崩溃,所谓的“雪崩效应”。
解决方案
服务熔断:当扇出链路的某个微服务不可⽤或者响应时间太⻓时,熔断该节点微服务的调⽤,进⾏服务的降级,快速返回错误的响应信息。当检测到该节点微服务调⽤响应正常后,恢复调⽤链路。
服务降级:先将⼀些不关紧的服务停掉(调⽤我的时候,给你返回⼀个预留的值,也叫做兜底数据),待渡过难关⾼峰过去,再把那些服务打开。
服务限流:服务降级是当服务出问题或者影响到核⼼流程的性能时,暂时将服务屏蔽掉,待⾼峰或者问题解决后再打开。
Hystrix基础知识
包裹请求: 使⽤@HystrixCommand注解添加Hystrix控制,包裹对依赖的调用逻辑。⾃动投递微服务方法。
跳闸机制:当某服务的错误率超过⼀定的阈值时,Hystrix可以跳闸,停⽌请求 该服务⼀段时间。
资源隔离:Hystrix为每个依赖都维护了⼀个⼩型的线程池(舱壁模式)。如果该线程池已满,发往该依赖的请求就被⽴即拒绝,⽽不是排队等待,从而加速失败判定。
监控:Hystrix可以近乎实时地监控运⾏指标和配置的变化,如成功、失败、超时等等。
回退机制:当请求失败、超时、被拒绝,或当断路器打开时,执⾏回退逻辑,回退逻辑自定义。
自我修复:断路器打开⼀段时间后,会⾃动进⼊“半开”状态。
舱壁模式(线程池隔离策略)
Hystrix线程池默认线程数是10个,当所有服务共用这个线程池,请求数量超过10个,那么一些服务就不可用了,因此诞生了舱壁模式,每一个控制方法创建一个线程池,也就是各自用自己的线程池。
Hystrix跳闸、自我修复
1)当调用出现问题时,开启⼀个时间窗(10s)。
2)在这个时间窗内,统计调用次数是否达到最小请求数?如果没有达到,则重置统计信息,回到第1步 如果达到了,则统计失败的请求数占所有请求数的百分⽐,是否达到阈值?如果达到,则跳闸(不再请求对应服务) 如果没有达到,则重置统计信息,回到第1步 。
3)如果跳闸,则会开启⼀个活动窗⼝(默认5s),每隔5s,Hystrix会让⼀个请求通过,到达那个问题服务,看是否调用成功,如果成功,重置断路器回到第1步,如果失败,回到第3步。
Hystrix DashBoard健康检查
Hystrix官方提供了基于图形化的 DashBoard(仪表板)监控平台。通过搭建一个DashBoard项目实现对Hystrix仪表板每个断路器(被 @HystrixCommand注解的⽅法)的状态监控。
Hystrix Turbine聚合监控
在集群环境下,结合dashboard仪表盘就需要每次输⼊⼀个监控数据流url进去查看,通过Hystrix Turbine聚合监控,专门新建一个Turbine监控项目可以实现聚合各个实例上的hystrix监控数据。
Feign远程调用组件
服务消费者调⽤服务提供者的时候使⽤RestTemplate技术需要拼接url以及getForObject存在硬编码。
Feign是Netflix开发的⼀个轻量级RESTful的HTTP服务客户端,以Java接⼝注解的⽅式调⽤Http请求,类似于dubbo,服务消费者拿到服务提供者的接⼝,然后像调用本地接⼝⽅法⼀样去调用,实际发出的是远程的请求。
本质:封装了Http调用流程,更符合⾯向接口化的编程习惯,类似于Dubbo的服务调用,基于代理实现。
Feign = RestTemplate+Ribbon+Hystrix
Feign对负载均衡的⽀持
Feign 本身已经集成了Ribbon依赖和⾃动配置,因此我们不需要额外引⼊依赖,可以通过 ribbon.xx 来进⾏全局配置,也可以通过服务名.ribbon.xx 来对指定服务进⾏ 细节配置配置。
Feign对熔断器的支持
⾃定义FallBack处理类(需要实现FeignClient接⼝);Feign集成了Hystrix,但是他们的超时是独立的,使用又是一起的,以最小值触发熔断。
Feign的日志级别配置
如果我们想看到Feign请求时的⽇志,首先要创建一个能被扫描到的配置类,通过这个类来加载配置的yml日志级别配置来实现。
Feign对请求压缩和响应压缩的⽀持
Feign ⽀持对请求和响应进⾏GZIP压缩,以减少通信过程中的性能损耗,以配置方式实现。
GateWay网关组件
网关是微服务架构中的重要组成部分,基于Spring5.0+SpringBoot2.0+WebFlux等技术开发,性能比Zuul高,为微服务架构提供⼀种简单有效的统⼀的API路由管理⽅式。不仅可以提供统⼀的路由⽅式,还可以做过滤、鉴权、 流量控制、熔断、路径重写、日志监控等等。
GateWay核心
路由(route):最基础的部分,由⼀个ID、一个目标URL、⼀系列的断⾔(匹配条件判断)和 Filter过滤器(精细化控制)组成。如果断言为true,则匹配该路由。
断⾔(predicates):匹配Http请求中的所有内容(包括请求头、请求参数等)
过滤器(filter):请求之前或者之后执⾏业务逻辑。
工作流程,核心路由转发+执行过滤链
客户端向Spring Cloud GateWay发出请求,然后在GateWay Handler Mapping中 找到与请求相匹配的路由,将其发送到GateWay Web Handler;Handler再通过指 定的过滤器链来将请求发送到我们实际的服务执⾏业务逻辑,然后返回。
GateWay路由规则
可以实现时间前后,区间匹配、Cookie正则匹配、Host匹配、Method匹配、远程地址匹配等等。
GateWay动态路由:GateWay⽀持⾃动从注册中⼼中获取服务列表并访问,即所谓的动态路由。
GateWay过滤器
从过滤器⽣命周期分pre和post
从过滤器类型分GateWayFilter和 GlobalFilter,常用GlobalFilter,即全局过滤器。
GateWay高可用:可以启动多个GateWay实例来实现⾼可⽤,在GateWay 的上游使⽤Nginx等负载均衡设备进⾏负载转发以达到高可用的目的。
Config分布式配置中心
Config Server是集中式的配置服务,⽤于集中管理应⽤程序各个环境下的配置。默认使⽤Git存储配置⽂件内容,也可以SVN。
配置中心的优点
1) 集中配置管理,多个微服务不同配置统一管控。
2) 不同环境不同配置,对于测试、生产等环境不同配置。
3) 实现运⾏期间可动态调整,如更改数据库连接信息,连接池等。
4) 配置内容发⽣变化,微服务可以⾃动更新配置
Server 端:提供配置⽂件的存储、以接口的形式将配置⽂件的内容提供出去,通过使⽤@EnableConfigServer注解在 Spring boot 应⽤中⾮常简单的嵌⼊。
Client 端:通过接口获取配置数据并初始化自己的应用。
Config配置手动刷新
1)Client客户端添加依赖springboot-starter-actuator(已添加)
2)Client客户端bootstrap.yml中添加配置(暴露通信端点
3)Client客户端使⽤到配置信息的类上添加@RefreshScope
4)⼿动向Client客户端发起POST请求,http://localhost:8080/actuator/refresh, 刷新配置信息
Config配置⾃动更新,结合消息总线BUS,支持(RabbitMq/Kafka)
消息总线Bus,即我们经常会使⽤MQ消息代理构建⼀个共⽤的Topic,通过这个Topic连接各个微服务实例,MQ⼴播的消息会被所有在注册中⼼的微服务实例监听和消费。就是通过⼀个主题连接各个微服务,打通脉络。
- Config Server服务端添加消息总线⽀持
- ConfigServer添加配置连接RabbitMq
- 微服务暴露端口
- 重启各个服务,更改配置之后,向配置中⼼服务端发送post请求http://localhost:9003/actuator/bus-refresh,各个客户端配置即可⾃动刷新,也支持定向刷新,跟服务名:端口号即可。
Stream消息驱动组件
Spring Cloud Stream 消息驱动组件帮助我们更快速,更⽅便,更友好的去构建消息驱动微服务的。Spring Cloud Stream进⾏了很好的上层抽象,可以让我们与具体消息中间件解耦合,屏蔽掉了底层具体MQ消息中间件的细节差异,就像Hibernate屏蔽掉了具体数据库(Mysql/Oracle⼀样)。
本质:屏蔽掉了底层不同MQ消息中间件之间的差异,统⼀了MQ的编程模型,降低了学习、开发、维护MQ的成本。
Spring Cloud Stream 是⼀个构建消息驱动微服务的框架。应⽤程序通过inputs(相 当于消息消费者consumer)或者outputs(相当于消息⽣产者producer)来与 Spring Cloud Stream中的binder对象交互,⽽Binder对象是⽤来屏蔽底层MQ细节 的,它负责与具体的消息中间件交互。对于我们来说,只需要知道如何使⽤Spring Cloud Stream与Binder对象交互即可。
Binder绑定器
通过它来屏蔽底层不同MQ消息中间件的细节差异,当需要更换为其他消息中间件时,我们需要做的就是更换对应的Binder绑定器。
Stream中的消息通信⽅式遵循了发布—订阅模式。当⼀条消息被投递到消息中间件之后,它会通过共享的Topic 主题进⾏⼴播,消息消费者在订阅的 主题中收到它并触发⾃身的业务逻辑处理。
常见问题及解决方案
Eureka 服务发现慢的原因
Eureka 服务发现慢的原因主要有两个,⼀部分是因为服务缓存导致的,另⼀部分是 因为客户端缓存导致的。
服务端缓存
服务注册到注册中⼼后,服务实例信息是存储在内存中,为了提高响应效率,Eureta内部加了两层缓存结构,一二级缓存之间会进行数据同步,默认30S,当Client获取服务实例数据时,会先从⼀级缓存中获取,如果⼀级缓存中不存在,再从⼆级缓存中获取,如果⼆级缓存也不存在,会触发缓存的加载,从存储层拉取数据到缓存中,然后再返回给Client,服务下线、过期、注册、状态变更等操作都会清除二级缓存中的数据,基于Guava,默认过期180S,因此产生的弊端也出现了,同步时间有30S,会导致服务发现慢的问题,解决办法要么缩短更新时间,要么禁用一级缓存。
客户端缓存
Eureka Client负责跟Eureka Server进⾏交互,默认30S拉取一次数据,也可以缩短拉取时间。
Ribbon会从Eureka Client中获取服务信息,默认也是30S,也可以缩短定时更新时间。
Spring Cloud 各组件超时,通过设置超时时间解决
Ribbon 如果采⽤的是服务发现⽅式,就可以通过服务名去进⾏转发,需要配置 Ribbon的超时,Hystrix的超时时间要⼤于Ribbon的超时时间,因为Hystrix将请求包装了起来,特别需要注意的是,如果Ribbon开启了重试机制,⽐如 重试3 次,Ribbon 的超时为 1 秒,那么 Hystrix 的超时时间应该⼤于 3 秒,否则就 会出现 Ribbon 还在重试中,⽽Hystrix已经超时的现象。
Feign Feign本身也有超时时间的设置,如果此时设置了Ribbon的时间就以Ribbon的时间为准,如果没设置Ribbon的时间但配置了Feign的时间,就以Feign的时间为准。