Sentinel Dashboard
本文范围
很多人第一次用 Sentinel,会以为 Dashboard 是一个像网关一样拦在请求前面的东西。这里先纠正一下:Dashboard 不是业务流量入口,它只是控制台。
真正拦请求的是业务服务进程里的 Sentinel 客户端。请求进入业务服务以后,Sentinel 客户端会根据本地规则判断:这次调用是放行、限流、熔断、热点参数限流,还是系统保护拒绝。
Dashboard 主要做三件事:
- 收客户端心跳,知道哪些应用接进来了。
- 拉客户端监控数据,展示实时 QPS、拒绝数、簇点链路。
- 管理规则,并把规则推给客户端,或者经过改造后写入 Nacos 这类规则中心。
所以生产上一定要记住一句话:业务服务不能依赖 Dashboard 才能跑,Dashboard 只是规则治理入口。Dashboard 挂了,已经在客户端内存里的规则还会继续执行;但是默认控制台新增的规则如果没有持久化,应用一重启就会丢。
这篇只讲 Sentinel Dashboard 和规则治理。限流算法不会展开成论文,Spring Cloud Alibaba 全家桶、Nacos 集群部署、Gateway 灰度、Dubbo 治理也不会铺开。它们会出现在配置和排障里,但不是主角。
当前写作时间是 2026-07-09。Sentinel GitHub Release 页面显示稳定版本主线最新为 1.8.10,2.0.0-alpha 仍按预览版本看待。新项目建议先按 1.8.10 做验证;老项目不要只追 Sentinel 版本,还要一起看 Spring Boot、Spring Cloud、Spring Cloud Alibaba、JDK、Nacos Client 的兼容关系。
前置条件
接入 Sentinel Dashboard 前,先确认这些条件:
- Java 运行环境、Dashboard 版本、客户端依赖版本、Spring Boot、Spring Cloud Alibaba、Nacos Client 兼容关系已经验证。
- Dashboard 只是控制台,业务限流熔断由客户端本地执行;生产规则必须有持久化来源,不能只存在 Dashboard 内存里。
- Dashboard 到业务服务客户端 API 端口
8719网络可达,业务服务到 Dashboard 心跳地址可达。 - 已规划应用名、资源名、规则命名、Nacos namespace/group/dataId 和配置格式,避免不同环境共用一份规则。
- 已准备规则变更审批、灰度、生效验证和回滚办法,尤其是核心接口的流控、熔断、授权和系统规则。
- Dashboard 入口、账号、密码、反向代理和访问来源已经收口,不直接暴露公网。
- 内网和离线环境已准备 Dashboard Jar、Maven 依赖、Nacos 依赖、校验文件、部署脚本和回滚包。
- 已准备观测入口,能看到 QPS、拒绝数、异常数、慢调用比例、业务错误率和规则变更记录。
先按一台 Linux 机器演示。生产环境可以换成 K8S、容器或统一发布平台,但第一遍最好先把 Jar 跑通,这样出问题时知道应该看哪个端口、哪个日志、哪个客户端 API。
这里假设:
| 项目 | 示例 |
|---|---|
| Dashboard 版本 | 1.8.10 |
| Dashboard 机器 | 10.10.10.20 |
| Dashboard 端口 | 8080 |
| 测试业务服务 | order-service |
| 业务服务端口 | 8800 |
| Sentinel 客户端 API 端口 | 8719 |
| Nacos 地址 | 10.10.10.30:8848 |
先建目录。如果目录已经有了就不用重复建;如果没有,就按下面的方式新建:
sudo mkdir -p /opt/sentinel-dashboard
sudo mkdir -p /data/sentinel-dashboard/package
sudo mkdir -p /data/sentinel-dashboard/logs
sudo chown -R app:app /opt/sentinel-dashboard /data/sentinel-dashboard这几条命令解决的是目录归属问题。/opt/sentinel-dashboard 放运行包,/data/sentinel-dashboard/package 放下载或内部分发过来的 Jar,/data/sentinel-dashboard/logs 放运行日志。
执行完以后看一下目录:
ls -ld /opt/sentinel-dashboard /data/sentinel-dashboard/logs正常应该看到目录属主是 app。如果还是 root,后面用 app 用户启动时可能没有写日志权限。
中国大陆、内网和离线环境怎么准备包
学习环境可以直接从 GitHub Release 下载:
export SENTINEL_VERSION=1.8.10
curl -fL \
-o sentinel-dashboard-${SENTINEL_VERSION}.jar \
"https://github.com/alibaba/Sentinel/releases/download/${SENTINEL_VERSION}/sentinel-dashboard-${SENTINEL_VERSION}.jar"
sha256sum sentinel-dashboard-${SENTINEL_VERSION}.jar这里要注意,不要把这个命令直接写进生产发布脚本里。国内公网访问 GitHub 不稳定,企业内网和离线环境也经常访问不了。生产更稳的做法是:
- 在能联网的机器上下载 Jar。
- 记录文件名、版本、大小和 SHA256。
- 上传到企业制品库、对象存储或内网文件仓库。
- 生产机器只从内网仓库拉取。
如果是离线交付,一般需要准备这些东西:
| 文件 | 用途 |
|---|---|
sentinel-dashboard-1.8.10.jar | 控制台运行包 |
| JDK 安装包 | 运行 Dashboard 和业务服务 |
| Maven 离线仓库 | 构建业务服务或改造 Dashboard |
| Nacos 安装包或镜像 | 存储规则 |
| systemd 文件或 K8S YAML | 标准部署模板 |
| 规则 JSON 模板 | 初始化和回滚 |
| SHA256 文件 | 校验包有没有损坏 |
不要只交一个 Jar。真正能落地的离线包,至少要能完成“安装、启动、验证、回滚”四个动作。
启动 Dashboard
先把 Jar 放到运行目录:
cd /opt/sentinel-dashboard
cp /data/sentinel-dashboard/package/sentinel-dashboard-1.8.10.jar ./
ls -lh sentinel-dashboard-1.8.10.jarls -lh 要能看到 Jar 文件大小。如果提示文件不存在,说明包还没有分发到机器,先别继续启动。
最小启动命令如下:
java \
-Dserver.port=8080 \
-Dsentinel.dashboard.auth.username=sentinel-admin \
-Dsentinel.dashboard.auth.password='change-me-now' \
-Dserver.servlet.session.timeout=7200 \
-Dcsp.sentinel.log.dir=/data/sentinel-dashboard/logs \
-jar sentinel-dashboard-1.8.10.jar这几个参数分别解决什么问题:
| 参数 | 作用 |
|---|---|
server.port | 指定控制台端口 |
sentinel.dashboard.auth.username | 登录用户名 |
sentinel.dashboard.auth.password | 登录密码 |
server.servlet.session.timeout | 登录会话过期时间 |
csp.sentinel.log.dir | Sentinel 相关日志目录 |
访问:
http://10.10.10.20:8080/访问后应该看到登录页。默认账号密码都是 sentinel,但是生产环境不要用默认密码。这里示例里已经改成了 sentinel-admin/change-me-now,上线时要换成团队自己的强密码或统一认证入口。
如果访问不了,先别急着怀疑 Sentinel,先按顺序查:
ps -ef | grep sentinel-dashboard | grep -v grep
ss -lntp | grep ':8080'
curl -I http://127.0.0.1:8080/
tail -n 100 /data/sentinel-dashboard/logs/*.log这几个命令分别看进程、端口、本机 HTTP 响应和日志。一般问题就三类:Jar 没启动、端口被占用、防火墙或安全组没放通。
用 systemd 托管 Dashboard
手工命令适合验证,生产一般需要交给 systemd 或发布平台托管。新建文件:
sudo vim /etc/systemd/system/sentinel-dashboard.service写入:
[Unit]
Description=Sentinel Dashboard
After=network-online.target
Wants=network-online.target
[Service]
User=app
Group=app
WorkingDirectory=/opt/sentinel-dashboard
ExecStart=/usr/bin/java \
-Dserver.port=8080 \
-Dsentinel.dashboard.auth.username=sentinel-admin \
-Dsentinel.dashboard.auth.password=change-me-now \
-Dserver.servlet.session.timeout=7200 \
-Dcsp.sentinel.log.dir=/data/sentinel-dashboard/logs \
-jar /opt/sentinel-dashboard/sentinel-dashboard-1.8.10.jar
Restart=on-failure
RestartSec=5
SuccessExitStatus=143
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target启动:
sudo systemctl daemon-reload
sudo systemctl enable sentinel-dashboard
sudo systemctl start sentinel-dashboard
sudo systemctl status sentinel-dashboard --no-pager正常应该看到 active (running)。如果不是,直接看日志:
journalctl -u sentinel-dashboard -n 200 --no-pager
journalctl -u sentinel-dashboard -f这里要注意,ExecStart 里的密码只是演示。生产不要把明文密码随便放进公共仓库,至少要限制 service 文件权限,最好由发布平台或 Secret 注入。
让服务接入 Dashboard
Dashboard 跑起来以后,还要让业务服务接入。最常见的是 Spring Cloud Alibaba 项目。
先引入依赖:
<dependencyManagement>
<dependencies>
<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>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>这里一般不要手工乱覆盖 Sentinel 子依赖版本。Spring Boot、Spring Cloud、Spring Cloud Alibaba 是一套版本组合,先按 BOM 来。
然后配置 application.yml:
server:
port: 8800
spring:
application:
name: order-service
cloud:
sentinel:
transport:
dashboard: 10.10.10.20:8080
port: 8719
management:
endpoints:
web:
exposure:
include: health,info,sentinel这段配置里有两个点最重要:
dashboard是 Dashboard 地址。port是业务服务本地起的 Sentinel HTTP API 端口,Dashboard 会通过这个端口拉规则和监控。
启动业务服务后,先访问一次接口:
curl http://127.0.0.1:8800/actuator/health
curl http://127.0.0.1:8800/orders/1这里要注意,服务刚启动但没有任何请求时,Dashboard 里可能还看不到簇点链路。一般需要有真实接口访问,Sentinel 客户端才会初始化资源并上报心跳。
再验证客户端 API:
curl http://127.0.0.1:8719/api
curl "http://127.0.0.1:8719/clusterNode"
curl "http://127.0.0.1:8719/getRules?type=flow"正常情况下:
/api能返回命令列表。/clusterNode能看到资源统计。getRules?type=flow没配规则时返回空数组或空内容。
如果 8719 访问不了,先看是不是端口冲突:
ss -lntp | grep 8719Sentinel 默认从 8719 开始,端口冲突时可能自动递增。生产建议显式固定端口,并确保 Dashboard 机器能访问业务服务这个端口。
纯 Sentinel 客户端怎么接
如果不是 Spring Cloud Alibaba starter,而是纯 Sentinel 接入,需要保证有 transport 模块:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.8.10</version>
</dependency>启动参数可以这样写:
java \
-Dproject.name=order-service \
-Dcsp.sentinel.dashboard.server=10.10.10.20:8080 \
-Dcsp.sentinel.api.port=8719 \
-Dcsp.sentinel.log.dir=/data/order-service/logs/csp \
-jar order-service.jar这几个 JVM 参数对应的就是应用名、Dashboard 地址、客户端 API 端口和 Sentinel 日志目录。
如果 Dashboard 能看到机器但拉不到监控,多半是 Dashboard 回连客户端 8719 失败。容器环境还要注意客户端上报的 IP 是否是 Dashboard 能访问到的 IP。
先定资源名,不然后面规则会乱
Sentinel 的规则都是围绕资源名生效的。资源名没定好,后面 Dashboard 里看到一堆 URL、方法名、RPC 名混在一起,很快就没人敢改规则。
常见资源名来源:
| 接入方式 | 资源名常见形式 |
|---|---|
| Spring MVC | /orders/{id} 或实际 URL |
@SentinelResource | 注解里的 value |
| 手工 API | SphU.entry("resourceName") |
| RestTemplate | GET:http://service/path 这类调用资源 |
| OpenFeign | Feign 调用资源 |
| Dubbo Provider | 接口全限定名或接口全限定名加方法签名 |
| Dubbo Consumer | 下游接口或方法资源 |
如果是核心业务方法,建议用 @SentinelResource 明确命名:
@GetMapping("/orders/{id}")
@SentinelResource(
value = "order.queryById",
blockHandler = "queryBlock",
fallback = "queryFallback"
)
public OrderDTO query(@PathVariable Long id) {
return orderService.query(id);
}
public OrderDTO queryBlock(Long id, BlockException ex) {
return OrderDTO.blocked(id);
}
public OrderDTO queryFallback(Long id, Throwable ex) {
return OrderDTO.fallback(id);
}这里要分清两个方法:
blockHandler处理 Sentinel 拒绝,比如限流、热点参数、系统规则、授权拒绝。fallback处理业务异常,比如下游异常、空指针、超时后的降级。
如果这两个都混成一个方法,线上排障时很难判断到底是被规则拦了,还是业务自己报错了。
配一条流控规则
先从最容易验证的 QPS 流控开始。比如我们要限制 order.queryById 每个实例每秒最多通过 20 次。
如果通过 Nacos 配置,内容可以写成:
[
{
"resource": "order.queryById",
"limitApp": "default",
"grade": 1,
"count": 20,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]几个字段先记住:
| 字段 | 说明 |
|---|---|
resource | 资源名,必须和代码或簇点链路里看到的一致 |
grade | 1 是 QPS,0 是并发线程数 |
count | 阈值 |
strategy | 0 直接,1 关联,2 链路 |
controlBehavior | 0 快速失败,1 Warm Up,2 排队等待 |
clusterMode | 是否集群流控 |
配置好以后,先看客户端有没有拿到规则:
curl "http://127.0.0.1:8719/getRules?type=flow"返回里应该能看到 order.queryById。如果看不到,说明规则还没有进入客户端,先不要压测,先查 Nacos 配置、Dashboard 推送或客户端日志。
然后用简单并发请求触发:
for i in {1..80}; do
curl -s http://127.0.0.1:8800/orders/1 >/dev/null &
done
wait触发后看业务返回。如果你配置了 blockHandler,应该能看到你自己的限流返回。如果没有配置,可能看到默认异常或框架默认错误响应。
再看簇点统计:
curl "http://127.0.0.1:8719/clusterNode"这里重点看两个数字:通过 QPS 和拒绝 QPS。只要拒绝数开始出现,说明规则命中了。
生产建议:
- 核心写接口优先快速失败,不要排队把线程拖住。
- 查询接口可以配 QPS,降级返回缓存或简化数据。
- 调下游的资源更适合并发线程数,防止慢下游拖垮自己。
- Warm Up 适合服务刚启动后的流量缓升,不是容量不足的万能药。
配熔断降级规则
熔断不是因为请求多,而是因为资源变慢或失败太多。比如支付接口平均响应变慢了,继续打它只会把调用方线程也拖死,这时就需要熔断。
慢调用比例规则可以这样写:
[
{
"resource": "payment.remotePay",
"grade": 0,
"count": 800,
"timeWindow": 10,
"minRequestAmount": 20,
"statIntervalMs": 1000,
"slowRatioThreshold": 0.5
}
]解释一下这条规则:
count: 800表示超过 800ms 算慢调用。minRequestAmount: 20表示请求数至少达到 20 才开始判断比例。slowRatioThreshold: 0.5表示慢调用比例达到 50% 会触发熔断。timeWindow: 10表示熔断后过 10 秒再尝试恢复。
验证时可以让下游接口故意 sleep:
for i in {1..40}; do
curl -s http://127.0.0.1:8800/payments/slow >/dev/null &
done
wait然后看客户端规则和资源统计:
curl "http://127.0.0.1:8719/getRules?type=degrade"
curl "http://127.0.0.1:8719/clusterNode" | grep payment.remotePay这里要注意,熔断规则最好配在调用端。谁会被慢下游拖住,就保护谁。不要只在服务提供方配规则,否则调用方线程已经被占住了,保护就晚了。
配热点参数规则
热点参数是 Sentinel 里很实用但也很容易踩坑的功能。比如商品详情接口,平时所有商品访问比较均匀,大促时某一个商品 ID 被打爆。这种情况按接口 QPS 限流会误伤其他商品,按参数限流更合适。
代码里先明确资源名:
@GetMapping("/items/{itemId}")
@SentinelResource(value = "item.detail", blockHandler = "itemBlock")
public ItemDTO detail(@PathVariable Long itemId) {
return itemService.detail(itemId);
}
public ItemDTO itemBlock(Long itemId, BlockException ex) {
return ItemDTO.busy(itemId);
}规则示例:
[
{
"resource": "item.detail",
"count": 50,
"grade": 1,
"durationInSec": 1,
"paramIdx": 0,
"controlBehavior": 0,
"maxQueueingTimeMs": 0,
"burstCount": 0,
"clusterMode": false,
"paramFlowItemList": [
{
"object": "10001",
"classType": "long",
"count": 10
}
]
}
]验证热点参数规则时,不要用 getRules?type=flow,热点参数有自己的命令:
curl "http://127.0.0.1:8719/getParamRules"能看到 item.detail 后,再压同一个热点值:
for i in {1..50}; do
curl -s http://127.0.0.1:8800/items/10001 >/dev/null &
done
wait常见坑:
resource和@SentinelResource的value不一致。paramIdx写错了,下标从 0 开始。- 参数类型没匹配,比如代码是
Long,规则里写了int。 - Dashboard 改造后把
ParamFlowRuleEntity原样写进 Nacos,客户端解析不到真正的ParamFlowRule。
生产建议是先把热点参数规则放到一个低风险查询接口上演练一遍,再用到交易链路。
配系统规则
系统规则是保护整个应用实例的入口流量。比如 CPU 使用率太高、入口 QPS 太高、线程数太高时,直接让 Sentinel 在入口层拒绝一部分请求。
规则示例:
[
{
"highestSystemLoad": -1,
"avgRt": -1,
"maxThread": -1,
"qps": 1000,
"highestCpuUsage": -1
}
]这里的 -1 表示这个指标不启用,只启用总体入口 QPS。系统规则影响面很大,一般不要一上来就配置很多项。
触发后常见异常是 SystemBlockException。排查时不要只看 Sentinel,还要看机器本身:
top
free -m
ss -s
curl "http://127.0.0.1:8719/getRules?type=system"容器环境尤其要注意 CPU 配额。宿主机看着很空,容器自己可能已经接近限制了。
配授权规则
授权规则用来根据来源做黑白名单。它不是登录认证,也不是完整权限系统,只是 Sentinel 资源维度的来源控制。
先在 Web 层解析来源:
@Component
public class HeaderOriginParser implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest request) {
String origin = request.getHeader("X-Service-Name");
if (origin == null || origin.isBlank()) {
return "unknown";
}
return origin;
}
}规则示例:
[
{
"resource": "order.create",
"limitApp": "gateway,trade-service",
"strategy": 0
}
]strategy 为白名单时,只有 gateway 和 trade-service 这种来源能通过。
验证:
curl -H "X-Service-Name: gateway" http://127.0.0.1:8800/orders
curl -H "X-Service-Name: unknown-service" http://127.0.0.1:8800/orders第一条应该通过,第二条应该被拒绝。这里要注意,来源字段最好由网关或服务框架统一注入,不要让用户直接传一个普通参数就能伪造来源。
集群流控什么时候用
单机流控是每个实例各算各的。假设 5 个实例,每个实例 QPS 阈值 100,总体可能通过 500 QPS。如果你要保护的是一个共享数据库、共享 Redis、第三方接口额度,就可能需要集群流控。
Sentinel 集群流控有两个角色:
| 角色 | 说明 |
|---|---|
| Token Client | 业务服务侧,发起 token 请求 |
| Token Server | 集群流控服务端,统一判断是否发放 token |
它适合这些场景:
- 多个实例共享同一个下游容量。
- 单机流量分布不均。
- 第三方接口有全局 QPS 配额。
这里要注意,集群流控比单机流控复杂很多。Token Server 自己要稳定,网络延迟会影响判断,规则也必须通过动态数据源管理。不要为了“看起来高级”把所有接口都上集群流控。一般从核心共享资源开始做,先压测,再上线。
默认 Dashboard 规则为什么不能直接上生产
默认 Dashboard 的规则推送大概是这样:
Dashboard 页面保存规则
-> Dashboard 调业务服务的 Sentinel API
-> 业务服务把规则放到本地内存这个模式很适合学习和验证,但生产有一个大问题:规则在客户端内存里,应用重启就没了。
所以生产一般需要规则中心。最常用的方式是 Nacos:
Dashboard 或规则发布平台
-> 写 Nacos 配置
-> 业务服务监听 Nacos
-> Sentinel 客户端刷新本地规则如果团队规模再大一点,最好变成:
Git 规则仓库
-> 评审
-> CI 校验 JSON
-> 发布到 Nacos
-> 客户端生效
-> 监控验证这样每次规则变更都有记录、有回滚,不会变成“谁在控制台点了一下没人知道”。
Sentinel 规则管理与生效链路图
下面这张图适合在生产方案评审时说明 Dashboard、客户端、8719 端口和规则中心的边界。重点是:Dashboard 不是业务流量入口,默认推送只是内存态;真正可回滚、可重启不丢的规则,要靠动态数据源或规则发布平台落到 Nacos、Apollo、File 这类规则源里。
上线检查时按图验证三条链路:第一,业务服务能向 Dashboard 上报,Dashboard 也能回连客户端 8719;第二,规则里的资源名能在 clusterNode 看到,客户端 getRules 或 getParamRules 能查到;第三,重启应用后规则仍然来自 Nacos/Apollo/File,而不是只停留在 Dashboard 内存推送里。
客户端从 Nacos 读取规则
先引入依赖:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.10</version>
</dependency>然后配置数据源:
spring:
application:
name: order-service
cloud:
sentinel:
transport:
dashboard: 10.10.10.20:8080
port: 8719
datasource:
flow-rules:
nacos:
server-addr: 10.10.10.30:8848
namespace: prod
group-id: SENTINEL_GROUP
data-id: order-service-flow-rules
data-type: json
rule-type: flow
degrade-rules:
nacos:
server-addr: 10.10.10.30:8848
namespace: prod
group-id: SENTINEL_GROUP
data-id: order-service-degrade-rules
data-type: json
rule-type: degrade
param-flow-rules:
nacos:
server-addr: 10.10.10.30:8848
namespace: prod
group-id: SENTINEL_GROUP
data-id: order-service-param-flow-rules
data-type: json
rule-type: param-flow
authority-rules:
nacos:
server-addr: 10.10.10.30:8848
namespace: prod
group-id: SENTINEL_GROUP
data-id: order-service-authority-rules
data-type: json
rule-type: authority
system-rules:
nacos:
server-addr: 10.10.10.30:8848
namespace: prod
group-id: SENTINEL_GROUP
data-id: order-service-system-rules
data-type: json
rule-type: system如果 Nacos 开了鉴权,还要按项目版本补充用户名、密码或认证配置。生产不要把 Nacos 密码写进公开仓库,至少要用环境变量、K8S Secret、配置平台或发布系统注入。
Nacos 里先放一个流控规则:
[
{
"resource": "order.queryById",
"limitApp": "default",
"grade": 1,
"count": 20,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]如果暂时没有规则,也建议放空数组:
[]不要让配置不存在。配置不存在时,有些项目启动没报错,但规则就是空的,排查时很绕。
验证 Nacos 规则是否进入客户端:
grep -i "nacos" /data/order-service/logs/app.log
grep -i "datasource" /data/order-service/logs/app.log
curl "http://127.0.0.1:8719/getRules?type=flow"
curl "http://127.0.0.1:8719/getRules?type=degrade"
curl "http://127.0.0.1:8719/getParamRules"看到规则进入客户端以后,再去压接口。如果客户端都没拿到规则,压接口没有意义。
Dashboard 修改规则怎么写回 Nacos
只配置客户端从 Nacos 读规则,还不等于 Dashboard 会把规则写回 Nacos。默认情况下:
Nacos 改规则 -> 客户端会监听生效
Dashboard 改规则 -> 通常不会自动回写 Nacos如果希望“在 Dashboard 点保存,规则进 Nacos”,就要改造 Dashboard。
Sentinel Dashboard 预留了两个核心扩展:
| 接口 | 作用 |
|---|---|
DynamicRuleProvider<T> | 从规则中心拉取规则 |
DynamicRulePublisher<T> | 把规则推送到规则中心 |
改造思路是:
查询规则
-> 从 Nacos 读 `${app}-flow-rules`
-> Rule 转 RuleEntity
-> Dashboard 页面展示
保存规则
-> Dashboard 校验表单
-> RuleEntity 转 Rule
-> 写入 Nacos
-> 客户端监听 Nacos 后刷新这里最容易出问题的是类型转换。Dashboard 页面使用的经常是 FlowRuleEntity、ParamFlowRuleEntity,客户端真正需要的是 FlowRule、ParamFlowRule。如果你把 Entity 原样写进 Nacos,客户端可能解析不到真正规则,热点参数规则尤其容易失效。
生产改造建议:
- 每类规则都单独写 Provider 和 Publisher。
- 发布到 Nacos 前,把 Entity 转成客户端 Rule。
- 从 Nacos 读回 Dashboard 前,把 Rule 转成 Entity。
- 每类规则都做 JSON 反序列化测试。
- 保存成功后调用客户端 API 抽样验证。
常见 dataId 命名:
| 规则类型 | Nacos dataId |
|---|---|
| 流控规则 | ${app}-flow-rules |
| 熔断规则 | ${app}-degrade-rules |
| 热点参数规则 | ${app}-param-flow-rules |
| 授权规则 | ${app}-authority-rules |
| 系统规则 | ${app}-system-rules |
RestTemplate、OpenFeign、Dubbo 怎么接
这几个不是本文主线,但项目里很常见,至少要知道怎么让 Sentinel 管住下游调用。
RestTemplate 一般这样配置:
@Bean
@LoadBalanced
@SentinelRestTemplate(
blockHandler = "handleException",
blockHandlerClass = RestTemplateFallback.class,
fallback = "fallback",
fallbackClass = RestTemplateFallback.class
)
public RestTemplate restTemplate() {
return new RestTemplate();
}处理方法签名要注意,多一个 BlockException:
public class RestTemplateFallback {
public static SentinelClientHttpResponse handleException(
HttpRequest request,
byte[] body,
ClientHttpRequestExecution execution,
BlockException ex) {
return new SentinelClientHttpResponse("{\"code\":429,\"message\":\"limited\"}");
}
}OpenFeign 要打开开关:
feign:
sentinel:
enabled: true然后配置 fallback:
@FeignClient(
name = "payment-service",
path = "/payments",
fallbackFactory = PaymentFeignFallbackFactory.class
)
public interface PaymentFeignClient {
@GetMapping("/{id}")
PaymentDTO query(@PathVariable Long id);
}Dubbo 需要适配模块:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-apache-dubbo-adapter</artifactId>
<version>1.8.10</version>
</dependency>Dubbo 资源名一般是:
接口资源: com.example.UserService
方法资源: com.example.UserService:getById(java.lang.Long)经验上,Provider 端主要防止自己被打垮,常配 QPS;Consumer 端主要防止慢下游拖垮自己,常配线程数和熔断降级。
控制台权限怎么做
Dashboard 自带的登录能力比较基础,只能算第一层门。生产至少要做下面几件事:
- 改默认账号密码。
- Dashboard 只允许内网、VPN、堡垒机或办公网访问。
- 通过 Nginx、Ingress 或网关增加 IP 白名单。
- 规则变更要记录操作人、时间、应用、资源、旧值、新值和原因。
- Nacos 开启鉴权,namespace 按环境隔离。
Nginx 内网访问控制可以这样写:
server {
listen 80;
server_name sentinel-dashboard.internal.example.com;
allow 10.0.0.0/8;
allow 172.16.0.0/12;
allow 192.168.0.0/16;
deny all;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}访问后应该先到公司内网入口,再到 Dashboard。不要把 Dashboard 直接暴露公网。
生产高可用边界
开源 Dashboard 不是完整商业化控制台。它可以作为规则管理入口和二次开发基础,但不要把它当唯一规则存储。
比较稳的生产形态是:
运维入口
-> Sentinel Dashboard
-> Nacos 规则配置
-> Sentinel 客户端监听
-> 业务服务本地执行规则更稳一点是:
Git 规则仓库
-> 规则评审
-> CI 校验 JSON
-> 发布平台写 Nacos
-> Dashboard 读取展示
-> 客户端监听生效
-> 监控验证这里要注意,Dashboard 可以部署多个实例提高访问可用性,但规则高可用靠的是规则中心,不是 Dashboard 自己内存。
生产拓扑要把 Dashboard、客户端 8719、Nacos 规则源和备份回滚放在一张图里。Dashboard 可以挂,业务规则不应该跟着丢;Nacos 可以回滚,客户端要能重新加载并用 getRules 验证。
这张图的重点是规则源和验证入口。Dashboard 页面保存成功,只说明控制台动作完成;真正上线要看 Nacos 里有没有规则、客户端 8719 返回的规则是否更新、拒绝 QPS 和业务错误率是否符合预期。回滚也不要只在页面上删除规则,要恢复规则源上一版 JSON,再抽样查客户端 API。
落地工程深水区
Sentinel 的生产难点不在“能不能点一条规则”,而在规则会不会稳定、可控、可回滚:
- 规则持久化是底线。默认 Dashboard 规则在内存里,应用重启会丢;生产至少要接 Nacos、Apollo、ZooKeeper 或自研规则中心。
- Dashboard 不能进入业务流量平面。它挂了不应该影响已加载规则的执行,业务服务也不能把 Dashboard 当强依赖。
- 资源名要治理。URL 带 ID、订单号、随机参数会导致簇点链路膨胀,规则也无法复用,要在入口处做资源名归一。
- 规则变更要审计。谁改了什么规则、影响哪些应用、何时生效、如何回滚,都要有记录。
- Nacos 配置要隔离。namespace、group、dataId、格式和权限要按环境拆开,生产规则不能和测试环境混用。
- 阈值要从观测数据来。流控阈值、熔断比例、慢调用 RT、系统保护水位要结合历史 QPS、P95/P99、容量压测和业务峰值,不要拍脑袋。
- 先灰度再全量。核心接口规则先在少量实例或低风险服务验证,观察拒绝数、错误率、延迟和业务指标后再扩大。
- 集群流控只在确有全局配额需求时使用。它会引入 token server、网络、容量和可用性问题,不是所有限流都要集群化。
- 权限要收住。Dashboard 管理员、规则编辑、只读观察、Nacos 写权限要区分,默认密码和公网入口必须处理。
- Sentinel 告警要和 Prometheus、日志、链路追踪联动。只看拒绝数不知道用户影响,只看错误率不知道是不是规则误伤。
Sentinel 规则不生效排查决策图
规则不生效时,先不要在页面上反复保存。下面这张图把机器发现、8719 回连、资源名、持久化、数据源、网关规则、集群模式和时间窗口拆开,适合上线后快速定位到底是哪一层没有生效。
这张图的核心原则是相信客户端 API。Dashboard 页面保存成功,只能说明控制台动作完成;真正生效要看客户端 8719 端口返回的规则、资源统计和业务返回。
排障:Dashboard 打不开
先看进程和端口:
systemctl status sentinel-dashboard --no-pager
journalctl -u sentinel-dashboard -n 200 --no-pager
ss -lntp | grep ':8080'
curl -v http://127.0.0.1:8080/如果 systemctl 不是 running,先看 journalctl。如果进程在但端口没有,检查启动参数。端口在但外部访问不了,检查防火墙、安全组、Nginx。
防火墙示例:
firewall-cmd --list-ports
firewall-cmd --add-port=8080/tcp --permanent
firewall-cmd --reload生产环境一般不建议直接开放 8080 给所有机器,而是通过内网入口转发。
排障:服务不上报
现象是 Dashboard 左侧没有应用,或者应用下面没有机器。
先访问业务接口,触发资源初始化:
curl http://127.0.0.1:8800/actuator/health
curl http://127.0.0.1:8800/orders/1再看客户端 API:
curl http://127.0.0.1:8719/api如果 8719 不通,说明客户端 API 没起来。常见原因:
- 没有引入 transport 或 starter。
spring.cloud.sentinel.transport.port没生效。- 端口冲突,Sentinel 自动换端口了。
再看 Dashboard 是否能访问业务服务的 8719:
curl -v http://业务服务IP:8719/api这里要注意,Dashboard 是要回连客户端的。容器里如果上报的是容器内部 IP,Dashboard 在外面访问不到,也会出现机器列表异常。
排障:簇点链路为空
应用上报了,但簇点链路没有资源,通常是没有真正访问到受保护资源。
先访问接口:
curl http://127.0.0.1:8800/orders/1
curl "http://127.0.0.1:8719/clusterNode"如果还是没有,看资源接入方式。
如果使用 @SentinelResource,检查这几项:
- 是否引入
sentinel-annotation-aspectj。 - 是否注册
SentinelResourceAspect。 - 方法是不是 Spring 代理调用,别在同一个类里 self-invocation。
- 资源名是不是和规则里一致。
排障:规则保存了但不生效
先不要猜,直接看客户端实际规则:
curl "http://127.0.0.1:8719/getRules?type=flow"
curl "http://127.0.0.1:8719/getRules?type=degrade"
curl "http://127.0.0.1:8719/getParamRules"如果客户端没有规则,就查 Nacos、Dashboard 推送或 datasource 配置。
如果客户端有规则,再看资源名:
curl "http://127.0.0.1:8719/clusterNode"常见原因:
- 规则里的
resource和实际资源名不一致。 - 阈值太高,测试请求没有打到阈值。
limitApp不是default,来源没匹配。- 热点参数规则用普通流控命令验证了。
- 多实例环境只看了一台机器,流量打到另一台。
这里有个经验:规则不生效时,优先相信客户端 API,不要只相信 Dashboard 页面。页面保存成功不等于每个客户端都已经加载成功。
排障:Nacos 改了客户端没生效
先确认应用连的是哪个 Nacos:
grep -R "server-addr" /data/order-service/config || true
grep -i "nacos" /data/order-service/logs/app.log再确认 namespace/group/dataId:
grep -R "order-service-flow-rules\\|SENTINEL_GROUP" /data/order-service/config || true常见坑:
namespace写了名称,实际需要 namespace ID。group-id和 Nacos 页面里的 group 不一致。data-id拼错。- Nacos 鉴权失败。
- JSON 不是数组。
- 规则字段类型错,客户端反序列化失败。
修复后不要只看 Nacos 页面,继续看客户端:
curl "http://127.0.0.1:8719/getRules?type=flow"排障:应用重启规则丢失
如果重启前规则有效,重启后规则没了,基本就是没有真正持久化。
排查:
curl "http://127.0.0.1:8719/getRules?type=flow"
grep -i "datasource" /data/order-service/logs/app.log如果没有 datasource 初始化日志,说明客户端还是在用内存规则。把规则写入 Nacos,并配置 spring.cloud.sentinel.datasource。
这里要注意,Dashboard 默认推规则只是推到客户端内存,不等于持久化。
发布规则和回滚
生产规则变更至少要记录这些字段:
| 字段 | 示例 |
|---|---|
| 应用 | order-service |
| 环境 | prod |
| 资源 | order.create |
| 类型 | flow |
| 阈值 | QPS 100 |
| 原因 | 大促入口保护 |
| 回滚值 | QPS 200 或删除规则 |
| 验证方式 | 客户端 API、压测、监控 |
建议把每次规则 JSON 备份下来:
mkdir -p rules-backup/order-service
cat > rules-backup/order-service/order-service-flow-rules-20260709-2000.json <<'JSON'
[
{
"resource": "order.create",
"limitApp": "default",
"grade": 1,
"count": 100,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
JSON回滚时不要只在页面上临时删一下。要回到规则源,把 Nacos 配置恢复到上一版,然后验证客户端重新加载。
上线前检查清单
上线前按这张表过一遍:
| 检查项 | 验证方式 |
|---|---|
| Dashboard 能登录 | 浏览器访问内网地址 |
| 默认密码已改 | 确认启动参数或认证配置 |
| 只允许内网访问 | Nginx、网关、安全组检查 |
| 客户端能上报 | Dashboard 机器列表有应用 |
| 客户端 API 固定 | curl 业务IP:8719/api |
| Nacos 规则存在 | Nacos 页面或 OpenAPI 查看 |
| 客户端加载规则 | getRules 和 getParamRules |
| 限流能触发 | 压测接口看拒绝数 |
| 降级能返回 | 触发 fallback 看返回格式 |
| 重启规则不丢 | 重启应用后再次查客户端规则 |
| 回滚能执行 | 恢复上一版 JSON 并验证 |
常用命令速查
Dashboard:
systemctl status sentinel-dashboard --no-pager
journalctl -u sentinel-dashboard -f
ss -lntp | grep ':8080'
curl -I http://127.0.0.1:8080/客户端:
curl http://127.0.0.1:8719/api
curl "http://127.0.0.1:8719/clusterNode"
curl "http://127.0.0.1:8719/getRules?type=flow"
curl "http://127.0.0.1:8719/getRules?type=degrade"
curl "http://127.0.0.1:8719/getParamRules"
curl "http://127.0.0.1:8719/getRules?type=system"
curl "http://127.0.0.1:8719/getRules?type=authority"简单压测:
for i in {1..100}; do
curl -s http://127.0.0.1:8800/orders/1 >/dev/null &
done
wait依赖排查:
mvn dependency:tree | grep -E "sentinel|nacos|spring-cloud-alibaba"
java -version官方文档入口
- Sentinel Dashboard:https://sentinelguard.io/zh-cn/docs/dashboard.html
- 动态规则扩展:https://sentinelguard.io/zh-cn/docs/dynamic-rule-configuration.html
- 流量控制:https://sentinelguard.io/en-us/docs/flow-control.html
- 热点参数限流:https://sentinelguard.io/en-us/docs/parameter-flow-control.html
- 系统自适应保护:https://sentinelguard.io/zh-cn/docs/system-adaptive-protection.html
- Sentinel FAQ:https://sentinelguard.io/zh-cn/docs/faq.html
- Spring Cloud Alibaba Sentinel 高级指南:https://sca.aliyun.com/en/docs/2023/user-guide/sentinel/advanced-guide/
- Sentinel Releases:https://github.com/alibaba/Sentinel/releases
- Nacos 部署文档:https://nacos.io/en-us/docs/deployment.html
