上一篇我们简单介绍了Sentinel如何使用,并演示如何限流,这篇继续其他功能的介绍吧。
Sentinel限流
关联模式,需要填写关联资源,当关联的资源达到阈值,就限流自己
设置流控规则,当byURL2接口QPS大于10的时候byURL进行限流
链路模式,只针对从指定链路访问到本资源的请求做统计,判断是否超过阈值,@SentinelResource加在service层
需求:有查询订单和创建订单业务,两者都需要查询商品。针对从查询订单进入到查询商品的请求统计,并设置限流。
步骤:
1.在OrderService中添加一个queryGoods方法,不用实现业务
2.在OrderController中,改造/order/query端点,调用OrderService中的queryGoods方法(/order/query -> queryGoods)
3.在OrderController中添加一个/order/save的端点,调用OrderService的queryGoods方法(/order/save -> queryGoods)
4.给queryGoods设置限流规则,从/order/query进入queryGoods的方法限制QPS必须小于2(设置/order/query qqs<2)
访问/order/query、/order/save资源
/order/query ##触发链路限流
/order/save ##不会触发链路限流
假如是sentinel 1.7.2以后版本,Sentinel Web过滤器默认会聚合所有URL的入口为sentinel_spring_web_context,因此单独对指定链路限流会不生效,需要在application.yml添加如下语句来关闭URL PATH聚合:
sentinel:
web-context-unify: false
Sentinel降级
@GetMapping("/rateLimit/byURL3")
@SentinelResource(value = "byURL3")
public CommonGenericResultRes byURL3(){
try {
Thread.sleep(200); //模拟耗时
}catch (Exception ignored){
}
return new CommonGenericResultRes("按url3限流测试ok");
}
这里表示熔断策略选择"慢调用比例",表示1秒(统计时长)内请求数超过10时,所有请求的响应时长(因为比例与阈值为1,所以是所有的请求响应时长)响应时间超过200毫秒,则对请求进行熔断,熔断时长为1秒钟。
Sentinel热点
Sentinel会利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。
配置byURL4接口第一个入参在2秒内同一入参访问次数大于5时访问失败
Jmeter配置P1参数递增,此时没有请求被拒绝
@GetMapping("/rateLimit/byURL4")
@SentinelResource(value = "byURL4")
public CommonGenericResultRes byURL4(@RequestParam("p1") int p1, @RequestParam("p2") int p2){
log.info("p1:{}, p2:{}", p1, p2);
return new CommonGenericResultRes("按url4限流测试ok");
}
Jmeter配置P1参数相同,满足5个后拒绝。2秒后清零重新判断
参数还可以配置额外项细化规则
文章参考:sentinel热点规则
Sentinel系统规则
系统在生产环境运行过程中,我们经常需要监控服务器的状态,看服务器CPU、内存、IO等的使用率;主要目的就是保证服务器正常的运行,不能被某些应用搞崩溃了;而且在保证稳定的前提下,保持系统的最大吞吐量。
Sentinel授权规则
黑白名单根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。
我们可以通过参数拦截,也可以通过IP等拦截,拦截是需要实现RequestOriginParser接口,比如调用接口的一个入参命名为origin,此时提供方代码
@Override
@SentinelResource(value = "byURL5")
public CommonGenericResultRes byURL5(@RequestParam("origin")String origin) {
return new CommonGenericResultRes();
}
import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
@Component
public class DefaultRequestOriginParser implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest request) {
String origin = request.getParameter("origin");
return origin;
}
}
调用方代码
@GetMapping("/rateLimit/byURL5")
public CommonGenericResultRes byURL5(){
CommonGenericResultRes commonGenericResultRes = XXX.byURL5("device-server");
return new CommonGenericResultRes("按url5限流测试ok");
}
sentinel配置,入参为device-server拦截,可以看到所有请求都失败了
文章参考:Sentinel限流熔断
其他:sentinel的集群使用是基于Nacos配置中心的;
原理:类似于单机限流,单机限流统计的qps在每个实例中单独统计,集群限流是有一个专门的实例(token server)来进行qps统计。其他实例(token client)在处理真正的业务之前会先向token server发送一个请求,如果server返回一个token,则说明集群qps未达到阈值,则可以继续处理业务,否则抛错。
实现:不会,请看其他博客教程Sentinel嵌入式集群模式搭建