目录
核心知识点
服务限流背景
在面对突发大量访问,或者恶意访问时,为了防止服务器宕机,提高服务器的稳定性,一般采用三大手段进行流量的控制,限流,熔断,降级,于是出现了一些流量控制软件,Sentinel就诞生了
Sentinel限流入门实践
第一步:下载Sentinel的Jar包,注意版本,和Nacos版本兼容性要匹配
https://github.com/alibaba/Sentinel/releases
第二步:在jar包的根目录打开cmd,运行以下命令
java -Dserver.port=8180 -Dcsp.sentinel.dashboard.server=localhost:8180 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.1.jar
-Dserver.port=8180 指定Sentinel的端口
-Dcsp.sentinel.dashboard.server=localhost:8180 指定Sentinel启动路径
-Dproject.name=sentinel-dashboard 指定Sentinel左侧默认菜单名
-jar sentinel-dashboard-1.8.1.jar jar包的文件名
在浏览器输入localhost:8180后,出现如下页面则访问成功,账号密码都是sentinel
第三步:添加依赖
<!--sentinel依赖限流依赖(相当于sentinel客户端对象), 此时项目会注入一个拦截器对象(spring mvc),此对象会对请求进行拦截, 记录请求的单位时间的访问次数--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
第四步:在bootstrap.yml配置Sentinel控制台信息
spring: application: cloud: sentinel: transport: dashboard: localhost:8180 #sentinel地址
第五步:编写测试方法
@RestController @RequestMapping("/provider") public class ProviderSentinelController { @GetMapping("/sentinel01") public String doSentinel01(){ return "sentinel01 test ..."; } }
第六步:测试,在浏览器输入访问路径后,查看Sentinel控制台的限流情况
Sentinel流控模式应用实践
第一步:点击蔟点链路,查看资源
第二步:点击流控进行配置
阈值类型:QPS为每秒的访问次数
单机阈值:允许每秒通过的访问次数
第三步:刷新测试限流情况
Sentinel限流的异常类型及异常处理器
异常处理接口为BlockExceptionHandler
此接口有一个实现类为DefaultBlockExceptionHandler
限流后控制台的异常内容就是在此接口写的
在SentinelWebAutoConfiguration这个类中,当我们没有实现BlockExceptionHandler接口时,系统就会使用DefaultBlockExceptionHandler
所以我们可以实现自己实现BlockExceptionHandler接口,控制限流后控制台的输出内容
@Component public class SentinelExceptionHandler implements BlockExceptionHandler { @Override public void handle(HttpServletRequest httpServletRequest, HttpServletResponse response, BlockException e) throws Exception { //设置响应状态码 response.setStatus(429); //设施设备响应编码格式 response.setContentType("text/html;charset=UTF-8"); //设置输出流对象 PrintWriter out = response.getWriter(); out.println("访问太过频繁,反应不过来啦!666"); out.flush(); out.close(); } }
测试限流异常前端页面输出内容
Sentinel流控模式分别是什么
直接,关联,链式
直接
默认流控模式为直接,当超过单机阈值的条件,就会限流
关联
关联模式,当关联的资源超过单机阈值,则自己限流
第一步:编写测试方法
@GetMapping("/sentinel02") public String doSentinel02(){ return "sentinel 02 test ..."; }
第二步:设置限流方式
第三步:快速刷新/provider/sentinel02资源,然后快速切换/provider/sentinel01进行刷新,测试限流情况
链路
链路的作用是当两个不同的资源访问同一个资源时,对其中的一个资源,也就是一个链路进行限流
第一步:编写测试方法,这里用到@SentinelResource注解
@Service public class ResourceService { /** * @SentinelResource 注解描述的方法为一个切入点方法, * 也就是说访问此方法时,要进行限流,具体的操作操作会放在切面的通知方法中 * value的属性值是对应的资源名 * */ @SentinelResource(value = "doGetResource") public String doGetResource(){ return "do Get Resource"; } }
使用两个不同的资源访问同一个资源
@Autowired private ResourceService resourceService; @GetMapping("/sentinel03") public String doSentinel03(){ resourceService.doGetResource(); return "sentinel03 test ..."; } @GetMapping("/sentinel04") public String doSentinel04(){ resourceService.doGetResource(); return "sentinel04 test ..."; }
第二步:因为版本的原因,所有的资源都默认在sentinel_default_context下,我们要通过配置文件打散链路聚焦
spring: application: cloud: sentinel: transport: dashboard: localhost:8180 #sentinel地址 web-context-unify: false #打散链路聚焦sentinel_spring_web_context,默认为true
第三步:配置链式限流模式
第四步:测试
限流的资源不符合单机阈值的条件时,被限流的链路报错
Sentinue自定义异常处理器
创建异常处理类
@Component @Slf4j public class ResourceBlockHandler { /** * 这里异常处理方法的要求: * 1.修饰符 public static * 2.返回值类型与@SentinelResource注解描述的方法返回指相同 * 3.参数列表与@SentinelResource注解描述的方法返回值相同 * 可以在最后多添加一个blockHandle参数 * */ public static String doHandle(BlockException ex){ log.error("被限流了"); return "访问太频繁"; } }
修改@Sentinel属性
@Service public class ResourceService { /** * @SentinelResource 注解描述的方法为一个切入点方法, * 也就是说访问此方法时,要进行限流,具体的操作操作会放在切面的通知方法中 * * 假如在访问这个资源方法时,出现了限流异常,我们可以自定义处理异常, * 具体方法: * 1)blockHandlerClass 指定异常处理类 * 2)blockHandler 指定方法名 * */ @SentinelResource(value = "doGetResource",blockHandlerClass = ResourceBlockHandler.class,blockHandler = "doHandle") public String doGetResource(){ return "do Get Resource"; } }
测试:
前端页面
后台异常日志输出
常见问题
Sentinel链路模式限流流程
AbstractSentinelInterceptor->controller->service(Proxy)->Ascept->Service(目标)
限流方式在切面的环绕通知方法内进行实现
Sentinel是如何进行限流的
实现SpriingMVC的拦截器接口,HandlerInterceptor,通过限流的算法对请求进行控制
你了解的Sentinel限流算法都有哪些
计数器:
令牌桶:设置一定的令牌,拿到令牌的资源才能被访问
漏桶:不管请求量多大,最终请求的资源都是匀速的
滑动窗口:Sentinue默认限流算法
Sentinue出现的异常父类类型是什么,默认实现类是什么
父类:BlockException
默认实现:DefaultBlockException
我们可以自定义限流处理吗
可以,直接或间接实现BlockException接口,并交给spring管理
@SentinelResourse注解的作用
标识目标方法为一个切面方法,底层可以通过aop方式对请求链路进行限制
Sentinel常见的流控效果有哪些
快速失败:
Warm Up:预热
排队: