启动Nacos
[xuej@localhost bin]$ ./startup.sh -m standalone
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.352.b08-2.el7_9.x86_64/bin/java -Djava.ext.dirs=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.352.b08-2.el7_9.x86_64/jre/lib/ext:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.352.b08-2.el7_9.x86_64/lib/ext -Xms512m -Xmx512m -Xmn256m -Dnacos.standalone=true -Dnacos.member.list= -Xloggc:/home/xuej/Downloads/nacos/logs/nacos_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M -Dloader.path=/home/xuej/Downloads/nacos/plugins,/home/xuej/Downloads/nacos/plugins/health,/home/xuej/Downloads/nacos/plugins/cmdb,/home/xuej/Downloads/nacos/plugins/selector -Dnacos.home=/home/xuej/Downloads/nacos -jar /home/xuej/Downloads/nacos/target/nacos-server.jar --spring.config.additional-location=file:/home/xuej/Downloads/nacos/conf/ --logging.config=/home/xuej/Downloads/nacos/conf/nacos-logback.xml --server.max-http-header-size=524288
nacos is starting with standalone
nacos is starting,you can check the /home/xuej/Downloads/nacos/logs/start.out
启动Sentinel Dashboard
INFO: Sentinel log output type is: file
INFO: Sentinel log charset is: utf-8
INFO: Sentinel log base directory is: /home/xuej/logs/csp/
INFO: Sentinel log name use pid is: false
INFO: Sentinel log level is: INFO
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.5.12)
2023-12-04 23:37:48.933 INFO 17286 --- [ main] c.a.c.s.dashboard.DashboardApplication : Starting DashboardApplication using Java 1.8.0_352 on localhost.localdomain with PID 17286 (/home/xuej/Documents/workspace-github/Sentinel/sentinel-dashboard/target/classes started by xuej in /home/xuej/Documents/workspace-github/Sentinel/sentinel-dashboard)
2023-12-04 23:37:48.951 INFO 17286 --- [ main] c.a.c.s.dashboard.DashboardApplication : No active profile set, falling back to 1 default profile: "default"
2023-12-04 23:37:50.734 INFO 17286 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2023-12-04 23:37:50.744 INFO 17286 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2023-12-04 23:37:50.745 INFO 17286 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.60]
2023-12-04 23:37:50.810 INFO 17286 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2023-12-04 23:37:50.810 INFO 17286 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1609 ms
2023-12-04 23:37:50.886 INFO 17286 --- [ main] c.a.c.s.dashboard.config.WebConfig : Sentinel servlet CommonFilter registered
2023-12-04 23:37:52.161 INFO 17286 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2023-12-04 23:37:52.185 INFO 17286 --- [ main] c.a.c.s.dashboard.DashboardApplication : Started DashboardApplication in 3.852 seconds (JVM running for 4.598)
2023-12-04 23:38:11.378 INFO 17286 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-12-04 23:38:11.379 INFO 17286 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2023-12-04 23:38:11.380 INFO 17286 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
启动本地服务
如下代码工程,展示的是如何对本地接口或本地服务做流控。更多流控场景代码示例,可参考后续发布的一系列实战文章。
pom.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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>tech.foolfish</groupId>
<artifactId>charge-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>charge-service</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.12.RELEASE</spring-boot.version>
<spring-cloud-alibaba.version>2.2.9.RELEASE</spring-cloud-alibaba.version>
<spring-cloud.version>Hoxton.SR10</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-cluster-client-default</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<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>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<configuration>
<mainClass>tech.foolfish.demo.ChargeServiceApplication</mainClass>
<skip>true</skip>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
application.properties
server.port=8081
spring.application.name=charge-service
spring.profiles.active=dev
spring.cloud.nacos.discovery.server-addr=localhost:8848
spring.cloud.nacos.discovery.username=nacos
spring.cloud.nacos.discovery.password=nacos
spring.cloud.nacos.config.server-addr=localhost:8848
spring.cloud.nacos.config.group=DEFAULT_GROUP
spring.cloud.nacos.config.file-extension=properties
spring.cloud.nacos.config.extension-configs[0].data-id=charge-service
spring.cloud.nacos.config.extension-configs[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.extension-configs[0].refresh=true
#spring.cloud.sentinel.enabled=false
spring.cloud.sentinel.log.switch-pid=true
spring.cloud.sentinel.transport.dashboard=localhost:8080
spring.cloud.sentinel.datasource.ds0.nacos.server-addr=localhost:8848
spring.cloud.sentinel.datasource.ds0.nacos.username=nacos
spring.cloud.sentinel.datasource.ds0.nacos.password=nacos
spring.cloud.sentinel.datasource.ds0.nacos.data-id=${spring.application.name}-flow-rules
spring.cloud.sentinel.datasource.ds0.nacos.group-id=SENTINEL_GROUP
spring.cloud.sentinel.datasource.ds0.nacos.rule-type=flow
spring.cloud.sentinel.datasource.ds1.nacos.server-addr=localhost:8848
spring.cloud.sentinel.datasource.ds1.nacos.username=nacos
spring.cloud.sentinel.datasource.ds1.nacos.password=nacos
spring.cloud.sentinel.datasource.ds1.nacos.data-id=${spring.application.name}-degrade-rules
spring.cloud.sentinel.datasource.ds1.nacos.group-id=SENTINEL_GROUP
spring.cloud.sentinel.datasource.ds1.nacos.rule-type=degrade
spring.cloud.sentinel.datasource.ds2.nacos.server-addr=localhost:8848
spring.cloud.sentinel.datasource.ds2.nacos.username=nacos
spring.cloud.sentinel.datasource.ds2.nacos.password=nacos
spring.cloud.sentinel.datasource.ds2.nacos.data-id=${spring.application.name}-system-rules
spring.cloud.sentinel.datasource.ds2.nacos.group-id=SENTINEL_GROUP
spring.cloud.sentinel.datasource.ds2.nacos.rule-type=system
spring.cloud.sentinel.datasource.ds3.nacos.server-addr=localhost:8848
spring.cloud.sentinel.datasource.ds3.nacos.username=nacos
spring.cloud.sentinel.datasource.ds3.nacos.password=nacos
spring.cloud.sentinel.datasource.ds3.nacos.data-id=${spring.application.name}-param-rules
spring.cloud.sentinel.datasource.ds3.nacos.group-id=SENTINEL_GROUP
spring.cloud.sentinel.datasource.ds3.nacos.rule-type=param-flow
spring.cloud.sentinel.datasource.ds4.nacos.server-addr=localhost:8848
spring.cloud.sentinel.datasource.ds4.nacos.username=nacos
spring.cloud.sentinel.datasource.ds4.nacos.password=nacos
spring.cloud.sentinel.datasource.ds4.nacos.data-id=${spring.application.name}-auth-rules
spring.cloud.sentinel.datasource.ds4.nacos.group-id=SENTINEL_GROUP
spring.cloud.sentinel.datasource.ds4.nacos.rule-type=authority
Java代码
package tech.foolfish.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ChargeServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ChargeServiceApplication.class, args);
}
}
package tech.foolfish.demo.local;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/demo")
@SuppressWarnings("rawtypes")
public class DemoController {
@Autowired
private DemoService demoService;
@GetMapping(value = "/hello")
public ResponseData hello() {
return demoService.hello();
}
}
package tech.foolfish.demo.local;
import org.springframework.stereotype.Service;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class DemoService {
@SentinelResource
public ResponseData hello() {
ResponseData responseData = new ResponseData("0", "成功", "你好 Sentinel");
log.info("responseData = {}", responseData);
return responseData;
}
}
package tech.foolfish.demo.local;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Throwables;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) {
ResponseData<?> restObject = null;
if (e instanceof FlowException) {
// 限流
restObject = new ResponseData("107002", "BlockExceptionHandler-接口限流", null);
} else if (e instanceof DegradeException) {
// 降级
restObject = new ResponseData("107003", "BlockExceptionHandler-服务降级", null);
} else if (e instanceof ParamFlowException) {
// 热点参数
restObject = new ResponseData("107004", "BlockExceptionHandler-热点参数限流", null);
} else if (e instanceof SystemBlockException) {
// 系统保护
restObject = new ResponseData("107005", "BlockExceptionHandler-触发系统保护规则", null);
} else if (e instanceof AuthorityException) {
// 授权规则
restObject = new ResponseData("107006", "BlockExceptionHandler-授权规则不通过", null);
} else {
restObject = new ResponseData("107001", "BlockExceptionHandler-接口异常", null);
}
// 返回json数据
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Type", "application/json;charset=UTF-8");
PrintWriter out;
try {
out = response.getWriter();
out.print(JSON.toJSON(restObject));
out.flush();
out.close();
} catch (IOException e1) {
log.error(Throwables.getStackTraceAsString(e));
}
}
}
package tech.foolfish.demo.local;
import lombok.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResponseData<T> {
private String errorId;
private String message;
private T data;
}
发起接口请求

配置规则
发起接口请求后,可以从簇点链路页面看到该接口请求的完整链路结构。

在簇点链路页面,可以快速新增规则。如下只是流控规则的示例,熔断、热点、授权,按需新增即可。

查看规则数据源

测试流控规则的效果
