一、Sentinel降级应用实践
1.What:对调用链路中不稳定的资源进行熔断降级
2.How:
准备调试代码:
//AtomicLong 类支持线程安全的自增自减操作
private AtomicLong atomicLong=new AtomicLong(1);
@GetMapping("/sentinel05")
public String doSentinel05() throws InterruptedException {
//获取自增对象的值,然后再加1
long num=atomicLong.getAndIncrement();
if(num%2==0){//模拟50%的慢调用比例
Thread.sleep(200);
}
return "sentinel 04 test";
}
这里表示熔断策略选择"慢调用比例",表示请求数超过3时,假如平均响应时间超过200毫秒的有30%,则对请求进行熔断,熔断时长为20秒钟,10秒以后恢复正常。
3.异常处理:
以下是降级的异常使用的是 BlockExceptionHandler
package com.jt.provider.controller;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
/**
* 自定义限流,降级等异常处理对象
*/
@Slf4j
@Component
public class ServiceBlockExceptionHandler
implements BlockExceptionHandler {
/**
* 用于处理BlockException类型以及子类类型异常
*/
@Override
public void handle(HttpServletRequest request,
HttpServletResponse response,
BlockException e) throws Exception {
//设置响应数据编码
response.setCharacterEncoding("utf-8");
//告诉客户端响应数据的类型,以及客户端显示内容的编码
response.setContentType("text/html;charset=utf-8");
//向客户端响应一个json格式的字符串
//String str="{\"status\":429,\"message\":\"访问太频繁了\"}";
Map<String,Object> map=new HashMap<>();
map.put("status", 429);
map.put("message","访问太频繁了");
String jsonStr=new ObjectMapper().writeValueAsString(map);
PrintWriter out = response.getWriter();
out.print(jsonStr);
out.flush();
out.close();
}
}
以下是链路流控的异常使用的是ResourceBlockHandler
- 小节面试分析
- 何为降级熔断?(让外部应用停止对服务的访问,生活中跳闸,路障设置-此路不通)
- 为什么要进行熔断呢?(平均响应速度越来越慢或经常出现异常,这样可能会导致调用链堆积,最终系统崩溃)
- Sentinel中限流,降级的异常父类是谁?(BlockException)
- Sentinel 出现降级熔断时,系统底层抛出的异常是谁?(DegradeException)
- Sentinel中异常处理接口是谁?(BlockExceptionHandler)
- Sentinel中异常处理接口下默认的实现类为? (DefaultBlockExceptionHandler)
- 假如Sentinel中默认的异常处理规则不满足我们的需求怎么办?(自己定义)
- 我们如何自己定义Sentinel中异常处理呢?(直接或间接实现BlockExceptionHandler )
- Sentinel熔断降级策略有哪些?(慢调用比例、异常比例、异常数)
Sentinel热点规则分析(重点)
1.what:
何为热点?热点即经常访问的数据
2.Why:
(1)某些商品流量大,其他商品流量很正常,就可以利用热点参数限流的方案。
(2)商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制。
(3)用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制。
3.How:
1.添加一个方法:
@GetMapping("/sentinel/findById")
@SentinelResource("resource")
public String doFindById(@RequestParam("id") Integer id){
return "resource id is "+id;
}
2.设置热点:
-
小节面试分析
-
如何理解热点数据?(访问频度比较高的数据,某些商品、谋篇文章、某个视频)
-
热点数据的限流规则是怎样的?(主要是针对参数进行限流设计)
-
热点数据中的特殊参数如何理解?(热点限流中的某个参数值的阈值设计)
- 对于热点数据的访问出现限流以后底层异常是什么?(ParamFlowException)
- 如何理解sentinel中的系统规则?(是对所有链路的控制规则,是一种系统保护策略)
- Sentinel的常用系统规则有哪些?(RT,QPS,CPU,线程,Load-linux,unix)
- Sentinel系统保护规则被触发以后底层会抛出什么异常?(SystemBlockException)
Sentinel授权规则(重要)
1.What:
黑白名单根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。例如微信中的黑名单。(黑名单不通过,白名单通过)。
2.How:
第一步:定义RequestOriginParser接口的实现类,在接口方法中解析请求参数数据并返回,底层会基于此返回值进行授权规则应用。使用了getParamete方法
@Component
public class DefaultRequestOriginParser implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest request) {
String origin = request.getParameter("origin");//这里的参数名会与请求中的参数名一致
return origin;
}
}
-
利用IP的方式设置黑白名单 (使用getRemoteAddr方法)
@Component
public class DefaultRequestOriginParser implements RequestOriginParser {
//解析请求源数据
@Override
public String parseOrigin(HttpServletRequest request) {
//获取访问请求中的ip地址,基于ip地址进行黑白名单设计(例如在流控应用栏写ip地址)
String ip= request.getRemoteAddr();
System.out.println("ip="+ip);
return ip;
}//授权规则中的黑白名单的值,来自此方法的返回值
}
- 小节面试分析
- 如何理解Sentinel中的授权规则?(对指定资源的访问给出的一种简易的授权策略)
- Sentinel的授权规则是如何设计的?(白名单和黑名单)
- 如何理解Sentinel中的白名单?(允许访问的资源名单)
- 如何理解Sentinel中的黑名单?(不允许访问的资源名单)、
- Sentinel如何识别白名单和黑名单?(在拦截器中通过调用RequestOriginParser对象的方法检测具体的规则)
- 授权规则中RequestOriginParser类的做用是什么?(对流控应用值进行解析,检查服务访问时传入的值是否与RequestOriginParser的parseOrigin方法返回值是否相同。)
- 总结(Summary)
- 总之,Sentinel可为秒杀、抢购、抢票、拉票等高并发应用,提供API接口层面的流量限制,让突然暴涨而来的流量用户访问受到统一的管控,使用合理的流量放行规则使得用户都能正常得到服务。
- 重难点分析
- Sentinel诞生的背景?(计算机的数量是否有限,处理能力是否有限,并发比较大或突发流量比较大)
- 服务中Sentinel环境的集成,初始化?(添加依赖-两个,sentinel配置)
- Sentinel 的限流规则?(阈值类型-QPS&线程数,限流模式-直接,关联,链路)
- Sentinel 的降级(熔断)策略?(慢调用,异常比例,异常数)
- Sentinel 授权规则设计?(掌握,黑白名单)
- FAQ分析
- 为什么要限流?
- 你了解的那些限流框架?(sentinel)
- 常用的限流算法有那些?(计数,令牌桶-电影票,漏桶-漏斗,滑动窗口)
- Sentinel有哪些限流规则?(QPS,线程数)
- Sentinel有哪些限流模式?(直接,关联-创建订单和查询订单,链路限流-北京六环外不限号,但是五环就限号)
- Sentinel 的降级(熔断)策略有哪些?(慢调用-响应时长,异常比例-异常占比,异常数)
- Sentinel 的热点规则中的热点数据?(热卖商品,微博大咖,新上映的电影)
拓展:23种设计模式