springcloud
2022-10-13 21:34:18 35 举报
AI智能生成
登录查看完整内容
Spring Cloud是一个基于Spring Boot实现的云应用开发工具,它为基于JVM的云应用开发中涉及的配置管理、服务发现、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等操作提供了一种简单的开发方式。Spring Cloud包含了多个子项目,如Spring Cloud Config、Spring Cloud Netflix、Spring Cloud OpenFeign等,它们分别用于配置管理、服务注册与发现、声明式服务调用等功能。通过使用Spring Cloud,开发者可以快速构建分布式系统的基础设施,提高开发效率和系统稳定性。
作者其他创作
大纲/内容
是一个基于 HTTP 和 TCP 客户端 的负载均衡的工具。
使用HttpClient 或RestTemplate调用远程服务对应的方法
RestTemplate提供了多种便捷访问远程Http服务的方法,是一种简单便捷的访问Restful服务模板类,是Spring 提供的用于访问Rest服务的客户端模板工具集
RestTemplate
@Configurationpublic class Config { @Bean @LoadBalanced // RestTemplate 已经被 Ribbon 代理 public RestTemplate restTemplate(){ return new RestTemplate(); }}
配置RestTempleate
使用 restTemplate 模拟 http 请求。
流程
Ribbon
Feign 是在 Ribbon的基础上进行了一次改进,是一个使用起来更加方便的 HTTP 客户端。
采用接口的方式, 只需要创建一个接口,然后在上面添加注解即可 ,将需要调用的其他服务的方法定义成抽象方法即可, 不需要自己构建http请求。
自定义一个接口,添加@FeignClient 注解,指定微服务名称
Feign
1.启动类使用的注解不同,Ribbon用的是@RibbonClient,Feign用的是@EnableFeignClients。
2.服务的指定位置不同,Ribbon是在@RibbonClient注解上声明,Feign则是在定义抽象方法的接口中使用@FeignClient声明。
3.调用方式不同,Ribbon需要自己构建http请求,模拟http请求然后使用RestTemplate发送给其他服务,步骤相当繁琐。Feign则是在Ribbon的基础上进行了一次改进,采用接口的方式,将需要调用的其他服务的方法定义成抽象方法即可,不需要自己构建http请求。不过要注意的是抽象方法的注解、方法签名要和提供服务的方法完全一致。
区别
feign本身里面就包含有了ribbon
feign自身是一个声明式的伪http客户端,写起来更加思路清晰和方便
fegin是一个采用基于接口的注解的编程方式,更加简便
feign的优点
Ribbon和Feign
Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。
简单的说就是将用户的请求平均分配到多个服务器上,从而达到系统的HA(高可用)。
Ribbon=负载均衡+RestTemplate调用\t
Ribbon负载均衡服务调用
Nginx是服务器负载均衡,客户端所有请求都会交给Nginx,然后,由nginx实现转发请求。即负载均衡是由服务器端完成的。
Ribbon本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用。
Ribbon客户端 VS Nginx服务端区别:
分支主题
架构说明
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId></dependency>
pom包
yml文件
环境搭建
IRule:根据特定算法从服务列表中选取一个要访问的服务(默认轮询)
注意点!!!这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,达不到特殊化订制的目的了。
Ribbon核心组件IRule
@Configurationpublic class MySelfRule { @Bean public IRule myRule(){ return new RandomRule();//定义为随机 }}
1.新建自定义规则类
@Component注意点
2.定义启动类
Ribbon自定义负载均衡算法
⑥ 负载均衡
Feign是一个声明式的web服务客户端,让编写web服务客户端变得非常容易,只需创建一个接口并在接口上添加注解即可
OpenFeign是什么?
利用Ribbon维护了Payment的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过Feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。
Feign集成了 Ribbon
Feign和OpenFeign两者区别
注意:openFeign也是自带ribbon <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
server: port: 80spring: application: name: cloud-consumer-feign-order80eureka: client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://localhost:7001/eureka
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")public interface PaymentFeignService { @GetMapping(value = "/payment/get/{id}") public CommonResult getPaymentById(@PathVariable("id") Long id);}
实现流程
使用Feign调用接口分两层,ribbon的调用和hystrix的调用,所以ribbon的超时时间和Hystrix的超时时间的结合就是Feign的超时时间
YML
一般情况下 都是 ribbon 的超时时间(<)hystrix的超时时间(因为涉及到ribbon的重试机制)
因为ribbon的重试机制和Feign的重试机制有冲突,所以源码中默认关闭Feign的重试机制
要开启Feign的重试机制如下:(Feign默认重试五次 源码中有)
如果在重试期间,时间超过了hystrix的超时时间,便会立即执行熔断,fallback。所以要根据上面配置的参数计算hystrix的超时时间,使得在重试期间不能达到hystrix的超时时间,不然重试机制就会没有意义
hystrix超时时间的计算: (1 + MaxAutoRetries + MaxAutoRetriesNextServer) * ReadTimeout 即按照以上的配置 hystrix的超时时间应该配置为 (1+1+1)*3=9秒
当ribbon超时后且hystrix没有超时,便会采取重试机制。当OkToRetryOnAllOperations设置为false时,只会对get请求进行重试。如果设置为true,便会对所有的请求进行重试,如果是put或post等写操作,如果服务器接口没做幂等性,会产生不好的结果,所以OkToRetryOnAllOperations慎用。
如果不配置ribbon的重试次数,默认会重试一次
hystrix和重试机制注意点
OpenFeign超时控制
#开启OpenFeign日志打印功能logging: level: com.atguigu.springcloud.service.PaymentFeignService: debug
OpenFeign日志打印功能
超链接
⑦ OpenFeign服务接口调用
复杂分布式体系结构中的应用程序有数十个依赖关系,每一个依赖关系在某些时候将不可避免的失败。
分布式系统面临的问题
多个微服务之间调用的时候,假如微服务A调用微服务B和微服务C,微服务B和微服务C又调用其他的微服务,这就是所谓的"扇出"。
如果扇出的链路上某个微服务的调用响应的时间过长或者不可用,对微服A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的"雪崩效应"。
服务雪崩
Hystrix是一个用于处理分布式系统的延迟和容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,
Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
向调用方返回一个符合预期的、可处理的备选响应(Fallback),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
Hystrix是什么
服务器忙,请稍候再试,不让客户端等待并立刻返回一个友好提示
程序运行异常
超时自动降级
服务熔断触发服务降级
人工降级
哪些情况会触发服务降级
一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法
主启动类激活@EnableHystrix测试超时和算数异常,都会走兜底方法——服务降级
每个业务方法对应一个兜底的方法,代码膨胀,代码耦合。统一通用处理和自定义独立处理的分开
存在问题
解决每个方法都要配置一个
服务降级,客户端去调用服务端,碰上服务端宕机或关闭,则无法实现降级。
和业务逻辑混耦合性太高
解决办法
服务降级
熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。
当检测到该节点微服务调用响应正常后,恢复调用链路。
熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状态,当失败的调用到一定阈值,缺省是10秒内20次调用并有50%的失败情况,就会启动熔断机制。熔断机制的注解是@HystrixCommand
熔断是什么
断路器注解
快照时间窗:断路器确定是否打开需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗,默认为最近的10秒。
快照时间窗
在快照时间窗内,必须满足请求总数阈值才有资格熔断。默认20,意味着在10秒内,如果该hystrix命令的调用次数不足20次,即使所有的请求都超时或其他原因失败,断路器都不会打开。
请求总数阈值
当请求总数在快照时间窗内超过了阈值,比如发生了30次调用,如果在这30次调用,有15次发生了超时异常,也就是超过50%的错误百分比,在默认设定50%阈值情况下,这时候就会将断路器打开。
错误百分比阈值
三个参数
再有请求调用的时候,将不会调用主逻辑,而是直接调用降级fallbak。通过断路器,实现了自动地发现错误并将降级逻辑切换为主逻辑,减少响应延迟的效果。
断路器打开之后的流程
当断路器打开,对主逻辑进行熔断之后,hystrix会启动一个休眠时间窗,在这个时间窗内,降级逻辑是临时的成为主逻辑,当休眠时间窗到期,断路器将进入半开状态,释放一次请求到原来的主逻辑上,如果此次请求正常返回,那么断路器将继续闭合,主逻辑恢复,如果这次请求依然有问题,断路器继续进入打开状态,休眠时间窗重新计时。
原来的主逻辑要如何恢复呢?
ALL配置(了解)
类比保险丝达到最大服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示
服务的降级->进而熔断->恢复调用链路
服务熔断限流
接近实时的监控
Hystrix能干嘛
⑧ Hystrix断路器
Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能,例如:熔断、限流、重试等
Gateway的目标提供统一的路由方式且基于Filter链的方式提供了网关基本的功能
基于Spring5.X+SpringBoot2.X和Project Reactor等技术开发的网关
具体实现是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通讯框架Netty。
Gateway是什么?
反向代理
鉴权
流量控制
熔断
日志监控
Gateway能干吗?
路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
pom文件
yml
路由流程
Route(路由)
开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
Predicate(断言)
指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。
路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用。
Filter的使用
在业务逻辑之前
pre
在业务逻辑之后
post
生命周期
impiemerts GlobalFilter ,Ordered
实现两个主要接口
全局日志记录
统一网关鉴权
能干嘛
自定义过滤器
Filter(过滤)
Gateway三大核心
⑨ Gateway
分布式链路请求跟踪
一个由客户端发起的请求在后端系统中会经过多个不同的服务节点调用来协同产生最后的请求结果,每一个前端请求都会形成一个复杂的分布式服务调用链路,链路中的任何一环出现高延时或错误都会引起整个请求最后的失败。
出现原因
<!--包含了sleuth+zipkin--><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId></dependency>
pom
spring zipkin: base-url: http://localhost:9411 sleuth: sampler: #采样率值介于0~1之间,1表示全部采样 probability: 1
服务提供者
<!--包含了sleuth+zipkin--><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId></dependency>
调用
服务消费者
⑩ SpringCloud Sleuth + Zipkin
分布式系统是建立在网络之上的软件系统。
什么是分布式?
集群指的是将几台服务器集中在一起,实现同一业务。而分布式则是各个服务器上的软件系统实现不同的业务,相互调用。
分布式与集群的关系
分布式中的每一个节点,都可以做集群。 而集群并不一定就是分布式的。
分布式与集群的特点
① 分布式
严格来说,SpringCloud是使用Rest方式进行服务之间交互的,不属于RPC
①\tRestAPI
RPC是指远程过程调用,是一种进程间通信方式。它允许程序调用另一个地址空间的过程或函数,像调用本地服务(方法)一样调用服务器的服务(方法)。
RPC是什么?
解决分布式系统的各个服务之间互相交互问题
RPC的目标
客户端调用服务方方法,等待直到服务方返回结果或者超时,再继续自己的操作
同步调用
客户端把消息发送给中间件,不再等待服务端返回,直接继续自己的操作。
异步调用
响应方式
1、 客户端(Client):服务调用方
2、 客户端存根(Client Stub):存放服务端地址信息,将客户端的请求参数打包成网络消息,再通过网络发送给服务方
3、 服务端存根(Server Stub):接受客户端发送过来的消息并解包,再调用本地服务
4、服务端(Server):真正的服务提供者。
具体实现步骤:https://blog.csdn.net/huojiao2006/article/details/82186389
RPC架构4个组件:
1、 服务调用方(client)(客户端)以本地调用方式调用服务;
2、 client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;在Java里就是序列化的过程
3、 client stub找到服务地址,并将消息通过网络发送到服务端;
5、 server stub根据解码结果调用本地的服务;
6、 本地服务执行处理逻辑;
7、 本地服务将结果返回给server stub;
8、 server stub将返回结果打包成消息,Java里的序列化;
9、 server stub将打包后的消息通过网络并发送至消费方
11、 服务调用方(client)得到最终结果。
具体实现步骤
② RPC
②服务之间的交互两种方式
通过设计保证系统可以并行处理很多请求。应对大量流量与请求
概念
硬件提升高并发
响应时间(RT)
系统在单位时间内处理请求的数量
吞吐量
每秒请求数
每秒事务数
承载的正常使用系统功能的用户的数量
并发用户数
高并发衡量指标
③ 高并发
主-备方式即指的是一台服务器处于某种业务的激活状态,另一台服务器处于该业务的备用状态
主-备方式
双主机方式即指两种不同业务分别在两台服务器上互为主备状态
双主机方式
服务集群部署
④ 高可用
管理服务与服务之间依赖关联,以实现服务调用,负载均衡、容错等,实现服务发现与注册。
什么是服务治理?
Eureka采用了CS的设计架构,Eureka Server作为服务注册功能的服务器,它是服务注册中心。
什么是服务注册
在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理概念)
核心设计思想
笔记
在应用启动后,将会在Eureka Server发送心跳(默认周期30秒)。如果Eureka Server在多个心跳周期内没有收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移出(默认90秒)
如何关闭自我保护机制
自我保护机制
Eureka和dubbo的区别
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
POM
eureka: instance: hostname: localhost client: register-with-eureka: false #默认true,是否将当前应用注册到eureka fetchRegistry: false #默认为true, 是否连接注册中心 service-url: defaultZone: http://localhost:7001/eureka
@EnableEurekaServer
主启动类
注册中心
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
eureka: client: register-with-eureka: true fetchRegistry: true service-url: defaultZone: http://localhost:7001/eureka
@EnableEurekaClient
消费者
配置
Eureka
⑤ 注册中心
Netflix主要提供的模块包括:服务发现、断路器和监控、智能路由、客户端负载均衡等。
Netflix
SpringCloud Alibaba简单理解就是替换Netflix那一套
一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。
Nacos = Eureka+Config+Bus
替代Eureka做服务注册中心
替代Config做服务配置中心
Nacos就是注册中心+配置中心的组合
一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
分区容忍性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。
如果在某个分布式系统中数据无副本, 那么系统必然满足强一致性条件, 因为只有独一数据,不会出现数据不一致的情况,此时C和P两要素具备,但是如果系统发生了网络分区状况或者宕机,必然导致某些数据不可以访问,此时可用性条件就不能被满足,即在此情况下获得了CP系统,但是CAP不可同时满足。因此在进行分布式架构设计时,必须做出取舍。当前一般是通过分布式缓存中各节点的最终一致性来提高系统的性能,通过使用多节点之间的数据异步复制技术来实现集群化的数据一致性。
Nacos支持AP和CP模式的切换
CAP原则
默认:MODE="cluster"集群方式启动,如果单机启动需要设置-m standalone参数,否则,启动失败。
默认Nacos使用嵌入式数据库实现数据的存储。所以,如果启动多个默认配置下的Nacos节点,数据存储是存在一致性问题的。为了解决这个问题,Nacos采用了集中式存储的方式来支持集群化部署,目前只支持MySQL 的存储。
Nacos默认自带的是嵌入式数据库derby,可以通过修改配置文件切换为mysql数据库
解压压缩包,修改配置文件端口号和数据库信息
cluster.conf
启动三个节点前,修改内存大小,不然会内存不足,导致启动失败
upstream nacoscluster{ server localhost:8848; server localhost:8849; server localhost:8850;}server{ listen 1111; server_name localhost; location / { proxy_pass http://nacoscluster; }
修改nginx的配置文件:
配置集群(一致性)
Nacos集群和持久化配置
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>
Nacos同springcloud-config一样,在项目初始化时,要保证先从配置中心进行配置拉取,拉取配置之后,才能保证项目的正常启动
springboot中配置文件的加载是存在优先级顺序的,bootstrap优先级高于applicationspring: cloud: nacos: discovery: server-addr: localhost:8848 #配置Nacos地址 config: server-addr: localhost:8848 #配置中心地址 file-extension: yaml #指定yaml格式的配置(yml和yaml都可以)#${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}#nacos-config-client-dev.yaml (一定要与file-extension值保持一致)
Nacos会记录配置文件的历史版本默认保留30天
最外层的namespace是可以用于区分部署环境的,Group和DataID逻辑上区分两个目标对象。
Nacos默认的命名空间是public,Namespace主要用来实现隔离。
Group默认是DEFAULT_GROUP,Group可以把不同的微服务划分到同一个分组里面去。
DataID=bootstrap+application
Namespace+Group+Data ID三者关系?为什么这么设计?
@RefreshScope //通过SpringCould原生注解@RefreshScope实现配置自动更新@Value("${config.info}") //对应nacos配置:nacos-config-client-dev.yaml private String configInfo;
主启动类加上@EnableDiscoveryClient
Nacos
把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
服务熔断
服务限流
服务使用中会出现的问题
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
spring: cloud: sentinel: transport: dashboard: localhost:8080 port: 8719 #默认8719,应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用HttpServer
基本介绍
直接(默认)
当关联的资源达到阈值时,就限流自己
关联
只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)
链路
流控模式
直接失败,抛出异常:Blocked by Sentinel (flow limiting)
直接->快速失败(默认的流控处理)
阈值除以coldFactor(默认值为3),经过预热时长后才会达到阈值
秒杀系统在开启的瞬间,会有很多流量上来,很有可能把系统打死,预热方式就是为了保护系统,可慢慢的把流量放进来,慢慢的把阈值增长到设置的阈值。
应用场景
预热
匀速排队,让请求以均匀的速度通过,阈值类型必须设置成QPS,否则无效。
等待的超时时间最多为20000毫秒。
排队等待
流控效果
流控规则
慢调用比例
异常比例
异常数
熔断规则
例子
自定义兜底降级
热点规则
熔断框架的比较
一旦我们停止应用,该应用的Sentinel规则将消失,生产环境需要将配置规则进行持久化
将限流配置规则持久化进Nacos保存,只要刷新只要Nacos里面的配置不删除,Sentinel上的流控规则持续有效
在nacos中添加规则,规则就会存储到其数据库,当加载项目时,规则就会存在于整个项目当中,就会被sentinel监控到,就会出现在sentinel的控制台中
如果更改sentinel中的热点规则,并不会同步到nacos中,如果想要双向绑定规则,需要更改源码
产生的问题
规则持久化
Sentinel
组件
⑪ SpringCloud Alibaba
springcloud
0 条评论
回复 删除
下一页