- 微服务雪崩问题:
- 微服务中,服务间的关系错综复杂,一个服务往往依赖多个其他服务,一个服务出现了问题,导致依赖他的微服务tomcat线程得不到释放,服务器支持的线程和并发数优先,越来越多的请求堆积,导致微服务资源耗尽而瘫痪,从而导致更多的微服务出问题, ,这就是雪崩问题
- 解决雪崩问题的常见四种方法,:
- 超时处理:设定超时时间,请求超过一定的时间,没有响应就返回错误信息,不会无休止的等待
- 仓壁模式:线程隔离
- 断路器(熔断):由断路器统计某个业务执行的异常比例,如果超出阈值则会熔断业务,拦截访问改业务的一直访问
- 限流:现在业务的访问的QPS,避免服务因流量的突增而故障
服务保护对比: | | Sentinel | Hystrix | | —- | —- | —- | | 隔离策略 | 信号量隔离 | 线程池隔离/信号量隔离 | | 熔断降级策略 | 基于慢调用比例或异常比例 | 基于失败比率 | | 实时指标实现 | 滑动窗口 | 滑动窗口(基于 RxJava) | | 规则配置 | 支持多种数据源 | 支持多种数据源 | | 扩展性 | 多个扩展点 | 插件的形式 | | 基于注解的支持 | 支持 | 支持 | | 限流 | 基于 QPS,支持基于调用关系的限流 | 有限的支持 | | 流量整形 | 支持慢启动、匀速排队模式 | 不支持 | | 系统自适应保护 | 支持 | 不支持 | | 控制台 | 开箱即用,可配置规则、查看秒级监控、机器发现等 | 不完善 | | 常见框架的适配 | Servlet、Spring Cloud、Dubbo、gRPC 等 | Servlet、Spring Cloud Netflix |
微服务整合sentinel
导入依赖
<!--sentinel--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>
修改application.yaml文件,添加下面内容:
server: port: 8088 spring: cloud: sentinel: transport: dashboard: localhost:8080
流量控制:
- 蔟点链路,:dispatcherservlet-service,mapoper就是一条蔟点链路,
- 默认情况下;sentinel会监控 springmvc的每一个端点:就是每一个controller的接口
- 流控和熔断都是对针对族点链路中的端点来设置,因此我们可以点击对应资源后面的按钮来设置规则:
- 流控:流量控制
- 降级:降级熔断
- 热点:热点参数限流,是限流的一种
- 授权:请求的权限控制
- 流控模式:
- 直接:统计当前资源的请求,触发阈值时对当前资源的限流,也是默认的设置
- 关联:统计与当前资源关联的另一个资源,到达阈值时对当前资源限流
- 链路:统计从指定链路访问到本资源的请求,触达阈值时;对指定的链路限流
- 流控效果:
- 快速失败:到达阈值时:新的请求会被立即拒绝并抛出FlowException异常,是默认的处理
- wram up:预热模式,对超出阈值的请求同样是拒绝抛出异常,但是这种模式的阈值时动态变化的,随时间的变化才会到达指定的阈值;
- 排队等待:当请求超过QPS阈值时,快速失败和warm up 会拒绝新的请求并抛出异常。
- 而排队等待则是让所有请求进入一个队列中,然后按照阈值允许的时间间隔依次执行。后
- 来的请求必须等待前面执行完成,如果请求预期的等待时间超出最大时长,则会被拒绝。
- 热点参数限流:
隔离和降级:
- Feign整合sentinel
- 作用 业务失败的时候 不可以直接报错,而是应该返回一个友好的结果,这个就是失败降级逻辑
- 2种方式:fallbackclass,无法对远程调用的异常处理
fallbackfactory,可以对远程调用的异常做处理 ```java package cn.itcast.feign.clients.fallback;
import cn.itcast.feign.clients.UserClient; import cn.itcast.feign.pojo.User; import feign.hystrix.FallbackFactory; import lombok.extern.slf4j.Slf4j; 步骤一:在feing-api项目中定义类,实现FallbackFactory:
//泛型是fenign
@Slf4j
public class UserClientFallbackFactory implements FallbackFactory
步骤二:在feing-api项目中的DefaultFeignConfiguration类中将UserClientFallbackFactory注册为一个Bean: @Bean public UserClientFallbackFactory userClientFallbackFactory(){ return new UserClientFallbackFactory(); }
import cn.itcast.feign.clients.fallback.UserClientFallbackFactory; import cn.itcast.feign.pojo.User; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable;
步骤三:在feing-api项目中的UserClient接口中使用UserClientFallbackFactory: @FeignClient(value = “userservice”, fallbackFactory = UserClientFallbackFactory.class) public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
} ```
- 线程隔离有2中实现方式:
- 线程池隔离:给每个服务分配一个线池,;利用线程池本身实现隔离
- 信号量隔离 :不创建线程池,使用计数器实现,记录访问的线程数量 达到上限时,不接受其他的请求
sentinel的规则默认是存储到内存中 关机重启就会消失;所以需要持久化
- 原始模式:Sentinel的默认模式,将规则保存在内存,重启服务会丢失。
pull模式:控制台将配置的规则推送到Sentinel客户端,而客户端会将配置规则保存在本地文件或数据库中。以后会定时去本地文件或数据库中查询,更新本地规则。
push模式:控制台将配置规则推送到远程配置中心,例如Nacos。Sentinel客户端监听Nacos,获取配置变更的推送消息,完成本地配置更新。
