目录
3.1 编写一个service,在里面添加一个dosomething方法
3.2 在Controller中声明两个方法,分别调用service中的dosomething方法
3.3.1 将SpringCloud Alibaba的版本调整2.1.1RELEASE
3.3.2 配置文件中关闭sentinel官方的CommonFilter实例化
3.3.3 添加配置类,自己构建CommonFilter实例
sentinel共有三种流控模式:
-
直接(默认):
接口达到限流条件时,开启限流 -
关联:
当关联的资源达到限流条件时,开启限流,适合做应用让步。例如为一个查询的接口添加关联流控,关联资源为一个更新的接口,当更新的接口达到阈值时,开启查询接口的限流,为更新接口让步服务器资源。 -
链路:
当从某个接口过来的资源达到限流条件时,开启限流
下面分别演示三种模式:
1 直接流控模式
直接流控模式是最简单的模式,当指定的接口达到限流条件时开启限流。效果参考
https://blog.csdn.net/qq_31155349/article/details/108470606
中的4.3.4小节
2 关联流控模式
关联流控模式指的是,当指定接口关联的接口达到限流条件时,开启对指定接口开启限流。
2.1 配置限流规则
将流控模式设置为关联,关联资源设置为/order/message2
2.2 jmeter压/order/message2接口
上图设置意味着每秒发送5次请求,即QPS=5。超过流控阈值。
jmeter启动压测,浏览器访问/order/message1接口,会发现已经被限流:
3 链路流控模式
链路流控模式指的是,当从某个接口过来的资源达到限流条件时,开启限流。它的功能有点类似于针对来源配置项,区别在于:
针对来源是针对上级微服务,而链路流控是针对上级接口,也就是说它的粒度更细。
3.1 编写一个service,在里面添加一个dosomething方法
package cn.jack.service.impl;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.stereotype.Service;
@Service
public class OrderServiceImpl3 {
@SentinelResource("dosomething") // 将此方法标注为sentinel的资源。value=资源名
public void dosomething() {
System.out.println("do something");
}
}
3.2 在Controller中声明两个方法,分别调用service中的dosomething方法
package cn.jack.controller;
import cn.jack.service.impl.OrderServiceImpl3;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class OrderController3 {
@Autowired
private OrderServiceImpl3 orderServiceImpl3;
@RequestMapping("/order/message1")
public String message1() {
this.orderServiceImpl3.dosomething();
return "message1";
}
@RequestMapping("/order/message2")
public String message2() {
this.orderServiceImpl3.dosomething();
return "message2";
}
}
3.3 禁止收敛URL的入口context
从
1.6.3
版本开始,Sentinel Web filter默认收敛所有URL的入口context,因此链路限流不生效。
1.7.0
版本开始(对应SCA的2.1.1.RELEASE),官方在CommonFilter 引入了
WEB_CONTEXT_UNIFY 参数,用于控制是否收敛context。将其配置为 false 即可根据不同的URL 进行链路限流。
SCA 2.1.1.RELEASE之后的版本,可以通过配置spring.cloud.sentinel.web-context-unify=false即可关闭收敛
我们当前使用的版本是SpringCloud Alibaba 2.1.0.RELEASE,无法实现链路限流。
目前官方还未发布SCA 2.1.2.RELEASE,所以我们只能使用2.1.1.RELEASE,需要写代码的形式实
现
上面这段是从百度down下来的,经过测试,SCA换成最新版本2.2.1.RELEASE仍然无效:
配置spring.cloud.sentinel.web-context-unify=false无效!!!
推荐做法仍然是关闭官方的CommonFilter实例化,自己手动实例化CommonFilter,设置WEB_CONTEXT_UNIFY=false
3.3.1 将SpringCloud Alibaba的版本调整2.1.1RELEASE
注意:最新版2.2.1RELEASE的CommonFilter类中,没有WEB_CONTEXT_UNIFY属性,此方法无效!!!
<spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
3.3.2 配置文件中关闭sentinel官方的CommonFilter实例化
spring:
cloud:
sentinel:
filter:
enabled: false
3.3.3 添加配置类,自己构建CommonFilter实例
package cn.jack.config;
import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterContextConfig {
@Bean
public FilterRegistrationBean sentinelFilterRegistration() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new CommonFilter());
registrationBean.addUrlPatterns("/*");
// 入口资源关闭聚合
registrationBean.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "false");
registrationBean.setName("sentinelFilter");
registrationBean.setOrder(1);
return registrationBean;
}
}
3.4 控制台配置限流规则
3.5 测试接口
浏览器分别对/order/message1和/order/message2进行频繁刷新访问,发现message1接口没有问题。而message2会有限流现象。
2020-09-08 23:43:49.498 ERROR 15400 --- [nio-8091-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.reflect.UndeclaredThrowableException] with root cause
com.alibaba.csp.sentinel.slots.block.flow.FlowException: null