feat: Sentinel 示例
This commit is contained in:
parent
a44e5f4c5d
commit
84ece9cf77
|
@ -11,5 +11,6 @@
|
|||
|
||||
<modules>
|
||||
<module>trace</module>
|
||||
<module>ratelimit</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
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>
|
||||
|
||||
<groupId>io.github.dunwu.spring</groupId>
|
||||
<artifactId>spring-distributed-ratelimit</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Spring::分布式::流量控制</name>
|
||||
|
||||
<modules>
|
||||
<module>sentinel</module>
|
||||
</modules>
|
||||
</project>
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
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.7.18</version>
|
||||
</parent>
|
||||
|
||||
<groupId>io.github.dunwu.spring</groupId>
|
||||
<artifactId>spring-distributed-ratelimit-sentinel</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<name>Spring::分布式::流量控制::Sentinel</name>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spring Web 的 Spring Boot 启动包,完成 Web 相关的自动化配置 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!-- Spring Test 的 Spring Boot 启动包,提供了一些便利的测试工具集 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-core</artifactId>
|
||||
<version>1.8.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.csp</groupId>
|
||||
<artifactId>sentinel-transport-simple-http</artifactId>
|
||||
<version>1.8.7</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,102 @@
|
|||
package example.spring.ratelimit.sentinel;
|
||||
|
||||
import com.alibaba.csp.sentinel.Entry;
|
||||
import com.alibaba.csp.sentinel.SphO;
|
||||
import com.alibaba.csp.sentinel.SphU;
|
||||
import com.alibaba.csp.sentinel.annotation.SentinelResource;
|
||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||
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.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
/**
|
||||
* 限流示例 Http 接口
|
||||
*
|
||||
* @author <a href="mailto:forbreak@163.com">Zhang Peng</a>
|
||||
* @date 2024-01-30
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
public class RateLimitController {
|
||||
|
||||
/**
|
||||
* 抛出异常的方式定义资源并限流
|
||||
*/
|
||||
@GetMapping("/limit1")
|
||||
public String limit1() {
|
||||
// 1.5.0 版本开始可以利用 try-with-resources 特性
|
||||
// 资源名可使用任意有业务语义的字符串,比如方法名、接口名或其它可唯一标识的字符串。
|
||||
try (Entry entry = SphU.entry("limit1")) {
|
||||
// 被保护的业务逻辑
|
||||
log.info("limit1 -> 请求通过");
|
||||
return "ok";
|
||||
} catch (BlockException e) {
|
||||
// 资源访问阻止,被限流或被降级
|
||||
// 在此处进行相应的处理操作
|
||||
log.error("limit1 -> 请求限流", e);
|
||||
return "failed";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回布尔值方式定义资源并限流
|
||||
*/
|
||||
@GetMapping("/limit2")
|
||||
public String limit2() {
|
||||
// 资源名可使用任意有业务语义的字符串
|
||||
if (SphO.entry("limit2")) {
|
||||
// 务必保证finally会被执行
|
||||
try {
|
||||
// 被保护的业务逻辑
|
||||
log.info("limit2 -> 请求通过");
|
||||
return "ok";
|
||||
} finally {
|
||||
SphO.exit();
|
||||
}
|
||||
} else {
|
||||
// 资源访问阻止,被限流或被降级
|
||||
// 进行相应的处理操作
|
||||
log.error("limit2 -> 请求限流");
|
||||
return "failed";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注解方式定义资源并限流
|
||||
*/
|
||||
@GetMapping("/limit3")
|
||||
@SentinelResource(value = "limit3")
|
||||
public String limit3() {
|
||||
try {
|
||||
log.info("limit3 -> 请求通过");
|
||||
return "ok";
|
||||
} catch (Exception e) {
|
||||
log.error("limit3 -> 请求限流", e);
|
||||
return "failed";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化流控规则
|
||||
*/
|
||||
@PostConstruct
|
||||
public void initFlowRules() {
|
||||
List<FlowRule> rules = new ArrayList<>();
|
||||
FlowRule rule = new FlowRule();
|
||||
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
|
||||
// 设置限流资源
|
||||
rule.setResource("limit1");
|
||||
// 设置 QPS
|
||||
rule.setCount(2);
|
||||
rules.add(rule);
|
||||
FlowRuleManager.loadRules(rules);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package example.spring.ratelimit.sentinel;
|
||||
|
||||
import com.alibaba.csp.sentinel.Entry;
|
||||
import com.alibaba.csp.sentinel.SphU;
|
||||
import com.alibaba.csp.sentinel.slots.block.BlockException;
|
||||
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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:forbreak@163.com">Zhang Peng</a>
|
||||
* @date 2024-01-30
|
||||
*/
|
||||
public class SentinelDemo {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 定义规则
|
||||
initFlowRules();
|
||||
|
||||
// 定义资源
|
||||
while (true) {
|
||||
// 1.5.0 版本开始可以利用 try-with-resources 特性
|
||||
// 资源名可使用任意有业务语义的字符串,比如方法名、接口名或其它可唯一标识的字符串。
|
||||
try (Entry entry = SphU.entry("HelloWorld")) {
|
||||
// 被保护的业务逻辑
|
||||
System.out.println("hello world");
|
||||
} catch (BlockException ex) {
|
||||
// 资源访问阻止,被限流或被降级
|
||||
// 在此处进行相应的处理操作
|
||||
System.err.println("blocked!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void initFlowRules() {
|
||||
List<FlowRule> rules = new ArrayList<>();
|
||||
FlowRule rule = new FlowRule();
|
||||
rule.setResource("HelloWorld");
|
||||
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
|
||||
// Set limit QPS to 20.
|
||||
rule.setCount(20);
|
||||
rules.add(rule);
|
||||
FlowRuleManager.loadRules(rules);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package example.spring.ratelimit.sentinel;
|
||||
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
/**
|
||||
* 启动类
|
||||
*
|
||||
* @author <a href="mailto:forbreak@163.com">Zhang Peng</a>
|
||||
* @date 2024-01-30
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class SpringBootSentinelApplication implements CommandLineRunner {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringBootSentinelApplication.class, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
${AnsiColor.BRIGHT_YELLOW}${AnsiStyle.BOLD}
|
||||
________ ___ ___ ________ ___ __ ___ ___
|
||||
|\ ___ \|\ \|\ \|\ ___ \|\ \ |\ \|\ \|\ \
|
||||
\ \ \_|\ \ \ \\\ \ \ \\ \ \ \ \ \ \ \ \ \\\ \
|
||||
\ \ \ \\ \ \ \\\ \ \ \\ \ \ \ \ __\ \ \ \ \\\ \
|
||||
\ \ \_\\ \ \ \\\ \ \ \\ \ \ \ \|\__\_\ \ \ \\\ \
|
||||
\ \_______\ \_______\ \__\\ \__\ \____________\ \_______\
|
||||
\|_______|\|_______|\|__| \|__|\|____________|\|_______|
|
||||
${AnsiColor.CYAN}${AnsiStyle.BOLD}
|
||||
:: Java :: (v${java.version})
|
||||
:: Spring Boot :: (v${spring-boot.version})
|
||||
${AnsiStyle.NORMAL}
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<configuration scan="true" scanPeriod="60 seconds" debug="false">
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%boldYellow(%thread)] [%highlight(%-5level)] %boldGreen(%c{36}.%M) - %boldBlue(%m%n)
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="example.spring" level="INFO" />
|
||||
|
||||
<root level="WARN">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</root>
|
||||
</configuration>
|
|
@ -1,6 +1,5 @@
|
|||
package example.spring.web.helloworld;
|
||||
|
||||
import example.spring.web.helloworld.entity.Weather;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
@ -9,27 +8,9 @@ import org.springframework.web.bind.annotation.RestController;
|
|||
@RestController
|
||||
public class HelloController {
|
||||
|
||||
private final WeatherService weatherService;
|
||||
|
||||
public HelloController(WeatherService weatherService) {
|
||||
this.weatherService = weatherService;
|
||||
}
|
||||
|
||||
@RequestMapping("hello")
|
||||
public String index() {
|
||||
return "Hello World";
|
||||
}
|
||||
|
||||
@RequestMapping("weather")
|
||||
public Weather weather() {
|
||||
log.info("查询南京市天气:");
|
||||
Weather weather = weatherService.getWeather("101190101");
|
||||
if (weather == null) {
|
||||
log.info("未查到数据!");
|
||||
return null;
|
||||
}
|
||||
weatherService.printBasicWeatherInfo(weather);
|
||||
return weather;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue