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