Spring Cloud Alibaba 的 Sentinel 组件提供了丰富的“流量控制“规则,
单体SpringBoot应用中也可以集成 Sentinel 来实现流量控制,本文主要讲 QPS流量控制。
SpringBoot集成Sentinel有两种方式:
一种是 dashboard控制面板的方式,需要下载sentinel-dashboard-1.6.3.jar
另一种是不需要dashboard,直接代码集成的方式。
这里采用的是第二种
注意:版本非常重要
有博文说 SpringBoot版本在 2.2.0 到 2.3.1之间才行,其他版本流量控制不生效。
我这里SpringBoot版本为 2.2.5.RELEASE,Sentinel版本为 2.2.1RELEASE(之前 sentinel版本为2.1.2.RELEASE,限流死活不生效)
1.添加Sentinel的Maven依赖包
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
2.定义限流规则
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
@Component
public class SentinelConfiguration implements InitializingBean{
public final static String QPS_LIMIT_GET_USER= "getUser";
@Override
public void afterPropertiesSet() {
initFlowQpsRule(QPS_LIMIT_GET_USER);
}
private void initFlowQpsRule(String resource) {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource(resource);
//设置限流规则为 QPS限流(每秒请求量)
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setCount(1); //1秒内允许请求1次
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
}
3.限流触发时的处理逻辑
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
@RestControllerAdvice
public class GlobalExceptionHandler{
/**
* 限流异常
*/
@ExceptionHandler(FlowException.class)
public String flowExceptionHandler(FlowException ex) {
return "---接口被限流了---";
}
}
注意:如果没有限流触发后的处理逻辑,会报以下异常
com.alibaba.csp.sentinel.slots.block.flow.FlowException: null
4.编写接口测试限流是否生效
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.qyp.hpa.config.SentinelConfiguration;
@RestController
public class UserController {
@RequestMapping("/getUser")
@SentinelResource(value = SentinelConfiguration.QPS_LIMIT_GET_USER)
public Map<String,Object> tempList() {
Map<String,Object> user = new HashMap<String,Object>();
user.put("name", "张三");
user.put("age", 30);
return user;
}
}
浏览器请求getUser接口,正常返回
浏览器连续快速点击刷新(1秒内点2次以上),触发接口限流规则,返回预设的限流触发消息。