引入依赖
代码语言:javascript
复制<!-- 必须的 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- sentinel 核心库 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.0</version>
</dependency>
实现流控
编码实现
代码语言:javascript
复制 private static final Logger logger = LoggerFactory.getLogger(HelloController.class);
private static final String RESOURCE_NAME = "hello";
@RequestMapping("/hello")
public String hello() {
Entry entry = null;
// 务必保证finally会被执行
try {
// 资源名可使用任意有业务语义的字符串
entry = SphU.entry(RESOURCE_NAME);
// 被保护的业务逻辑
// do something...
String str = "hello world";
logger.info(" " str);
return str;
} catch (BlockException e1) {
// 资源访问阻止,被限流或被降级
// 进行相应的处理操作
logger.info("block!!!!!");
return "被流控了!!!!";
} catch (Exception e) {
// 若需要配置降级规则。则需要通过这种方式记录业务异常
Tracer.traceEntry(e, entry);
} finally {
if (entry != null) {
entry.exit();
}
}
return null;
}
代码语言:javascript
复制 @PostConstruct
private static void initFlowControlRules() { // 通常设置在服务提供方
// 流控规则列表
List<FlowRule> flowRuleList = new ArrayList<>();
// 流控规则
FlowRule helloFlowRule = new FlowRule();
// 设置流控的资源名称
helloFlowRule.setResource(RESOURCE_NAME);
// 设置流控规则 QPS
helloFlowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 设置流控的阈值
// Set limit QPS to 20
helloFlowRule.setCount(1);
flowRuleList.add(helloFlowRule);
FlowRuleManager.loadRules(flowRuleList);
}
注解实现
代码语言:javascript
复制<!-- @SentinelResource -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>1.8.0</version>
</dependency>
代码语言:javascript
复制 @Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
代码语言:javascript
复制/**
* 1. 使用注解@SentinelResource
* 2. 使用了 Spring AOP
* 3. 通过配置的方式将 SentinelResourceAspect 注册为一个 Spring Bean
*/
@Configuration
public class AopConfiguration {
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
}
代码语言:javascript
复制 /**
* 使用注解 使用Sentinel
*
* @SentinelResource: 依赖:
* <dependency>
* <groupId>com.alibaba.csp</groupId>
* <artifactId>sentinel-annotation-aspectj</artifactId>
* <version>1.8.0</version>
* </dependency>
* 1. value: 资源名称
* 2. blockHandler 流控降低处理器 (默认和接口实现方法在同一个类中)
* 3. blockHandlerClass 指定处理器类
* 4. fallback 业务异常处理
* 5. fallbackClass 指定异常处理器类
* 6. blockHandler 和 fallback 同时配置, blockHandler 优先级高
* 7. exceptionsToIgnore 排除不需要处理的异常 -> exceptionsToIgnore = {}
*/
@RequestMapping("/user")
@SentinelResource(value = USER_RESOURCE_NAME, blockHandler = "blockHandlerForGetUser",
// fallback = "fallBackForGetUser",
exceptionsToIgnore = {})
public User getUser(String id) {
// int i = 1 / 0;
return new User(id, "Quentin");
}
/**
* 注意:
* 1. 必须是public, 若放在其他类中 blockHandlerClass 则必须为 public static
* 2. 返回值 需和原接口方法的返回值保持一致 且 参数包含原方法的参数
* 3. 额外增加 异常参数 BlockException
*
* @param id
* @param be
* @return
*/
public User blockHandlerForGetUser(String id, BlockException be) {
logger.info(" 注解流控");
return new User(id, "被流控了!!!");
}
代码语言:javascript
复制 @PostConstruct
private static void initFlowControlRules() { // 通常设置在服务提供方
// 流控规则列表
List<FlowRule> flowRuleList = new ArrayList<>();
// 流控规则
FlowRule userFlowRule = new FlowRule();
// 设置流控的资源名称
userFlowRule.setResource(USER_RESOURCE_NAME);
// 设置流控规则 QPS
userFlowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 设置流控的阈值
// Set limit QPS to 20
userFlowRule.setCount(1);
flowRuleList.add(userFlowRule);
FlowRuleManager.loadRules(flowRuleList);
}