Nacos。如使用docker安装可参考:docker-compose部署Nacos
改造好的 sentinel-dashboard。具体改造可参考改造sentinel-dashboard,使用Nacos持久化规则(详细)
创建项目 hello-sentinel。
pom.xml 文件如下:
<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.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.3.0.RELEASEversion>
<relativePath/>
parent>
<groupId>top.zysitegroupId>
<artifactId>hello-sentinelartifactId>
<version>1.0.0-SNAPSHOTversion>
<name>hello-sentinelname>
<description>Demo project for Spring Bootdescription>
<packaging>pompackaging>
<modules>
<module>hello-sentinel-gatewaymodule>
<module>hello-sentinel-normalmodule>
modules>
<properties>
<spring-cloud.version>Hoxton.SR5spring-cloud.version>
<admin-starter-server.version>2.2.3admin-starter-server.version>
<spring-cloud-alibaba.version>2.2.0.RELEASEspring-cloud-alibaba.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring-cloud.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-alibaba-dependenciesartifactId>
<version>${spring-cloud-alibaba.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>de.codecentricgroupId>
<artifactId>spring-boot-admin-starter-serverartifactId>
<version>${admin-starter-server.version}version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<version>2.4.0version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.75version>
dependency>
dependencies>
dependencyManagement>
<repositories>
<repository>
<id>springid>
<url>https://maven.aliyun.com/repository/springurl>
<releases>
<enabled>trueenabled>
releases>
<snapshots>
<enabled>trueenabled>
snapshots>
repository>
repositories>
project>
创建两个子模块:hello-sentinel-normal
,和hello-sentinel-gateway
。
hello-sentinel-normal
子模块 pom.xml 文件如下:
<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">
<parent>
<artifactId>hello-sentinelartifactId>
<groupId>top.zysitegroupId>
<version>1.0.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<groupId>top.zysitegroupId>
<artifactId>hello-sentinel-normalartifactId>
<packaging>jarpackaging>
<name>hello-sentinel-normalname>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
配置使用 普通服务(非网关)中配置
章节下的配置。
创建一个 测试 Controller:
package top.zysite.hello.sentinel.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Random;
/**
* Hello控制器
*
* @author Leo
* @create 2021/1/27 16:25
**/
@RestController
@RequestMapping("hello")
public class HelloController {
// @SentinelResource(value = "hello", fallback = "sentinelFallback")
@GetMapping("sentinel")
public String sentinel(){
return "hello sentinel";
}
// @SentinelResource(value = "degrade", fallback = "sentinelFallback")
@GetMapping("degrade")
public String degrade(){
//测试降级
if(new Random().nextInt() % 2 == 0) {
return "hello degrade";
} else {
throw new RuntimeException("RuntimeException");
}
}
@GetMapping("param")
public String paramFlowRule(String param1, Integer param2) {
return "paramFlowRule";
}
public String sentinelFallback() {
return "hello fallback";
}
}
hello-sentinel-gateway
子模块 pom.xml 文件如下:
<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">
<parent>
<artifactId>hello-sentinelartifactId>
<groupId>top.zysitegroupId>
<version>1.0.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<groupId>top.zysitegroupId>
<artifactId>hello-sentinel-gatewayartifactId>
<packaging>jarpackaging>
<name>hello-sentinel-gatewayname>
<dependencies>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
配置使用 网关中配置
章节下的配置。
如果项目使用Spring Cloud
,引入 Spring Cloud 整合依赖。
完整引入如下依赖:
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cspgroupId>
<artifactId>sentinel-datasource-nacosartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
在各个服务的配置文件中配置接入控制台并从 Nacos 获取限流、降级规则:
Sentinel 限流规则默认存在内存中,重启、掉线就会丢失,为了持久化限流规则,可以使用 Nacos 作为 Sentinel 限流规则数据源,此前已经对 sentinel-dashboard 进行了改造。完整application.yml
配置如下:
server:
port: 9003
nacos:
server-addr: localhost:8848
sentinel:
group-id: SENTINEL_GROUP
data-type: json
spring:
application:
name: hello-sentinel-normal
cloud:
nacos:
discovery:
server-addr: ${
nacos.server-addr}
sentinel:
transport:
dashboard: localhost:8888
port: 8719
#客户端ip,多网卡时多次连接可能识别不同
# client-ip: X.X.X.X
datasource:
#限流规则
flow:
nacos:
server-addr: ${
nacos.server-addr}
data-id: ${
spring.application.name}-flow-rules
group-id: ${
sentinel.group-id}
data-type: ${
sentinel.data-type}
rule-type: flow
#降级规则
degrade:
nacos:
server-addr: ${
nacos.server-addr}
data-id: ${
spring.application.name}-degrade-rules
group-id: ${
sentinel.group-id}
data-type: ${
sentinel.data-type}
rule-type: degrade
#热点规则
param:
nacos:
server-addr: ${
nacos.server-addr}
data-id: ${
spring.application.name}-param-rules
group-id: ${
sentinel.group-id}
data-type: ${
sentinel.data-type}
rule-type: param_flow
#系统规则
system:
nacos:
server-addr: ${
nacos.server-addr}
data-id: ${
spring.application.name}-system-rules
group-id: ${
sentinel.group-id}
data-type: ${
sentinel.data-type}
rule-type: system
#授权规则
authority:
nacos:
server-addr: ${
nacos.server-addr}
data-id: ${
spring.application.name}-auth-rules
group-id: ${
sentinel.group-id}
data-type: ${
sentinel.data-type}
rule-type: authority
#取消延迟加载
eager: true
management: #开启SpringBoot Admin的监控
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
feign:
sentinel:
enabled: true #开启feign对sentinel的支持
从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流:
网关需要额外引入 Sentinel 整合网关的依赖,完整依赖如下:
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-alibaba-sentinel-gatewayartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cspgroupId>
<artifactId>sentinel-datasource-nacosartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
完整application.yml
配置如下:
server:
port: 9100
nacos:
server-addr: localhost:8848
sentinel:
group-id: SENTINEL_GROUP
data-type: json
spring:
application:
name: hello-sentinel-gateway
cloud:
gateway:
discovery:
locator:
lower-case-service-id: true
enabled: true
routes:
- id: hello-sentinel-normal
uri: lb://hello-sentinel-normal
predicates:
- Path=/normalservice/**
filters:
- StripPrefix=1
nacos:
discovery:
server-addr: ${
nacos.server-addr}
sentinel:
transport:
dashboard: localhost:8888
port: 8719
#客户端ip,多网卡时多次连接可能识别不同
# client-ip: x.x.x.x
datasource:
#网关route纬度限流规则
gateway-flow:
nacos:
server-addr: ${
nacos.server-addr}
data-id: ${
spring.application.name}-gateway-flow
group-id: ${
sentinel.group-id}
data-type: ${
sentinel.data-type}
rule-type: gw_flow
#网关api纬度限流规则
gateway-api:
nacos:
server-addr: ${
nacos.server-addr}
data-id: ${
spring.application.name}-gateway-api
group-id: ${
sentinel.group-id}
data-type: ${
sentinel.data-type}
rule-type: gw_api_group
#降级规则
degrade:
nacos:
server-addr: ${
nacos.server-addr}
data-id: ${
spring.application.name}-degrade-rules
group-id: ${
sentinel.group-id}
data-type: ${
sentinel.data-type}
rule-type: degrade
#系统规则
system:
nacos:
server-addr: ${
nacos.server-addr}
data-id: ${
spring.application.name}-system-rules
group-id: ${
sentinel.group-id}
data-type: ${
sentinel.data-type}
rule-type: system
#取消延迟加载
eager: true
management: #开启SpringBoot Admin的监控
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
feign:
sentinel:
enabled: true #开启feign对sentinel的支持
在 启动类 main 方法里加入一条语句设置当前应用为网关类型:
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class GateWayApplication {
public static void main(String[] args) {
//设置为网关类型
System.setProperty("csp.sentinel.app.type", "1");
SpringApplication.run(GateWayApplication.class, args);
}
}
详情:Spring Cloud Gateway 网关限流
访问 localhost:8888 ,进入 sentinel 控制台,账户密码都为 sentinel ,登录进去。
启动 hello-sentinel-normal 和 hello-sentinel-gateway。
可以看到都已经连接到 sentinel 控制台了。在控制台 里创建、编辑各种规则,规则都会以配置文件形式保存在 Nacos 中。为 hello-sentinel-normal
添加一条限流规则,然后进入 Nacos 控制台 localhost:8848 查看。
可以通过一些工具如 jmeter 测试限流是否正常。
通过@SentinelResource
注解中的fallback
或者defaultFallback
属性指定熔断方法,进行熔断处理。
SentinelResource注解属性详情
示例代码:
@Service
public class DemoService {
@SentinelResource(value = "DemoService#hello", defaultFallback = "helloFallback")
public String hello(String name) {
return "Hello, " + name;
}
public String helloFallback(String name, Throwable t) {
if (BlockException.isBlockException(t)) {
return "Blocked by Sentinel: " + t.getClass().getSimpleName();
}
return "Oops, failed: " + t.getClass().getCanonicalName();
}
}
依赖前面已经引入。
配置文件中配置feign.sentinel.enabled=true
,开启对 feign 的支持。
示例代码:
@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
public interface EchoService {
@RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
String echo(@PathVariable("str") String str);
}
class FeignConfiguration {
@Bean
public EchoServiceFallback echoServiceFallback() {
return new EchoServiceFallback();
}
}
class EchoServiceFallback implements EchoService {
@Override
public String echo(@PathVariable("str") String str) {
return "echo fallback";
}
}
在构造 RestTemplate
bean 的时候需要加上 @SentinelRestTemplate
注解。
示例代码:
@Bean
@SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
public RestTemplate restTemplate() {
return new RestTemplate();
}
@SentinelRestTemplate
注解的属性支持限流(blockHandler
, blockHandlerClass
)和降级(fallback
, fallbackClass
)的处理。
源码:上述例子源码
我的更多文章尽在:我的个人博客