快速开始
欢迎来到 Sentinel 的世界!这篇新手指南将指引您快速入门 Sentinel。
Sentinel 的使用可以分为两个部分:
核心库(Java 客户端)
: 不依赖任何框架/库,能够运行于 Java 7 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持(见 主流框架适配)。控制台(Dashboard)
:Dashboard 主要负责管理推送规则、监控、管理机器信息等。
1. 引入 Sentinel 依赖
- 创建一个 SpringBoot 项目,命名为
sentinel-quick-start
- 创建一个
pom.xml
,添加以下Spring Boot 依赖
。
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.11.RELEASE</version>
<relativePath/>
</parent>
<groupId>cn.calvin</groupId>
<artifactId>sentinel-quick-start-01</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- SpringBoot 启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- SpringBoot Web 请求控制器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- SpringBoot 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Sentinel 核心 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.2</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<!-- Fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.56</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
xml
<!-- Sentinel 核心 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.2</version>
</dependency>
2. 定义资源
资源
是 Sentinel 中的核心概念之一。在项目下创建包名:
cn.calvin.sentinel.controller
cn.calvin.sentinel.domain
创建接口访问控制类:
UserController.java
java
package cn.calvin.alibaba.sentinel.controller;
import cn.calvin.alibaba.sentinel.domain.User;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Calvin
* @date 2021/9/14
* @since v1.0.0
*/
@Slf4j
@RestController
@RequestMapping(value = "/api/v1/user")
public class UserController {
// 定义资源名称
private static final String USER_RESOURCE_NAME = "/api/v1/user/getById";
@GetMapping("/getById")
public JSONObject getById(@RequestParam("id") String id) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("code", 200);
jsonObject.put("msg", "获取用户信息成功!");
jsonObject.put("data", null);
try {
// 1.sentinel 针对定义资源进行限制
Entry entry = SphU.entry(USER_RESOURCE_NAME);
// 2.被保护的逻辑,执行的业务逻辑
User calvinUser = User
.builder()
.id("1")
.username("Calvin")
.password("******")
.birthday("1994-12-14")
.genden(1)
.build();
if (calvinUser.getId().equals(id)) {
jsonObject.put("data", calvinUser);
}
return jsonObject;
} catch (BlockException be){
// 处理被流控的逻辑
log.info("block!");
jsonObject.put("code",500);
jsonObject.put("msg", "当前被限流");
jsonObject.put("data", null);
return jsonObject;
}
}
}
- 创建实体数据访问层:
User.java
java
package cn.calvin.alibaba.sentinel.domain;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 用户
*
* @author Calvin
* @date 2021/9/14
* @since v1.0.0
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
/** 用户ID */
private String id;
/** 用户名 */
private String username;
/** 密码 */
private String password;
/** 生日 */
private String birthday;
/** 性别 */
private Integer genden;
/** 头像 */
private String avater;
}
java
// 定义资源名称
private static final String USER_RESOURCE_NAME = "/api/v1/user/getById";
try {
// 1.sentinel 针对资源进行限制的
Entry entry = SphU.entry(USER_RESOURCE_NAME);
// 2.被保护的逻辑,执行的业务逻辑
User calvinUser = User
.builder()
.id("1")
.username("Calvin")
.password("******")
.birthday("1994-12-14")
.genden(1)
.build();
if (calvinUser.getId().equals(id)) {
jsonObject.put("data", calvinUser);
}
return jsonObject;
} catch (BlockException be){
// 处理被流控的逻辑
log.info("block!");
jsonObject.put("code",500);
jsonObject.put("msg", "当前被限流");
jsonObject.put("data", null);
return jsonObject;
}
注意:资源定义
- 资源定义一般针对某个接口上
- 资源定义也可以在 @RequestMapping(value = "/api/v1/user") 上,但下面方法具体接口也受到限流。
3. 定义规则
- 通过流控规则来指定允许该资源通过的请求次数。
- 在项目下创建包名:
cn.calvin.alibaba.sentinel.config
- 创建Sentinel流控规则配置:
SentinelRulesConfig.java
java
package cn.calvin.alibaba.sentinel.config;
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;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
/**
* Sentinel 流控规则配置
*
* @author Calvin
* @date 2021/9/14
* @since v1.0.0
*/
@Slf4j
@Configuration
public class SentinelRulesConfig {
// 定义资源名称
private static final String RESOURCE_NAME = "/api/v1/user/getById";
/**
* 初始化流控规则
*/
@PostConstruct
public void initFlowRules() {
// 添加: 流控规则
List<FlowRule> rules = new ArrayList<>();
// 构建流控规则: 资源名称、QPS规则、阈值(每秒最多只能通过1个请求。)
FlowRule flowRule = this.flowRuleBuild(RESOURCE_NAME, RuleConstant.FLOW_GRADE_QPS, 1);
rules.add(flowRule);
// 加载配置好的规则
FlowRuleManager.loadRules(rules);
log.info(">>>>>>>>> 初始化流控规则: {} >>>>>>>>>", rules);
}
/**
* 流控规则构建
*
* @param resourceName 资源名称
* @param grade 流控规则
* @param count 阈值
* @return {@link FlowRule}
*/
private FlowRule flowRuleBuild(String resourceName, int grade, double count) {
// 创建:流控规则
FlowRule rule = new FlowRule();
// 设置规则对应的【资源名称】
rule.setResource(resourceName);
// 设置流控规则为: QPS
rule.setGrade(grade);
// 设置受保护的资源阈值
rule.setCount(count);
return rule;
}
}
4. 项目启动
- 创建一个启动类
SentinelQuickStartApplication.java
java
package cn.calvin.alibaba.sentinel;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SentinelQuickStartApplication {
public static void main(String[] args) {
SpringApplication.run(SentinelQuickStartApplication.class, args);
}
}