此处会列出关于 Sentinel 的常见问题以及相应的注意事项和解决方案。
Q: 配置参数如何指定?
A: 可通过 JVM -D 参数指定。除 project.name
之外,其余参数还可通过 properties 文件指定,路径为 ${home}/logs/csp/${project.name}.properties
。详见 启动项配置文档。
Q: 可否自定义 properties 文件的位置或日志文件的位置?
A: 1.3.0 版本开始支持配置日志文件的目录,可以参考 启动项配置文档;若希望自定义 properties 文件的位置或使用其它的加载方式,可以结合 Spring Cloud Alibaba Sentinel 使用。
Q: Sentinel 可否用于生产环境?
A: 当然可以!Sentinel 可用于生产环境,但若要在生产环境中使用 Sentinel 控制台则还需要进行一些改造。
A: 可以参考 Guideline: 从 Hystrix 迁移到 Sentinel。
Q: 我的服务是基于 Spring Boot 和 Dubbo 编写的,Sentinel 有相应的适配吗?
A: 当然啦,Sentinel 针对常用框架和库进行了适配,包括 Web Servlet、Dubbo、Spring Boot / Spring Cloud、gRPC 等,可以参见 主流框架的适配。
Q: Sentinel 的性能如何?只进行埋点不配置规则,仅统计指标信息会有多少性能损耗?
A: 引入 Sentinel 带来的性能损耗非常小。只有在业务单机量级超过 25W QPS 的时候才会有一些显著的影响(10% 左右),单机 QPS 不太大的时候损耗几乎可以忽略不计。性能测试报告见 Benchmark。
Q: 是否需要在初始化时手工调用 InitExecutor.doInit()
方法进行相应的初始化?
A: 不需要,sentinel-core 的 Env 类通过 static 块调用了此方法进行初始化,在首次调用资源时即可触发。一些 demo 中手动调用此方法是为了不让进程退出。
Q: 降级规则生效后,除了抛异常之外还有没有其它的处理方式?
A: 可以利用 Sentinel 注解 来配置 fallback 函数,在资源被降级时进行相应处理。另外,对于 Dubbo 服务,我们支持注册全局的 fallback 函数,可参考 Dubbo 适配文档。
A: Sentinel 支持按来源限流,可以参考 基于调用关系的限流。注意 origin 数量不能太多,否则会导致内存暴涨,并且目前不支持模式匹配。
若 Web 应用使用了 Sentinel Web Filter,并希望对 HTTP 请求按照来源限流,则可以自己实现 RequestOriginParser
接口从 HTTP 请求中解析 origin 并注册至 WebCallbackManager
中。示例代码:
WebCallbackManager.setRequestOriginParser(ServletRequest::getRemoteAddr);
特别地,流控应用如果使用了 Sentinel Dubbo Adapter,同时 Dubbo 的消费者也引入了 Sentinel Dubbo Adapter(用于透传 dubboApplication
这个参数),则填 Dubbo 调用方的 application name 就好(注意是 Dubbo 里配置的应用名而不是 Sentinel 的应用名),消费端引入 adapter 就会自动透传,否则需要自己传来源应用名。
注意来源信息(origin
)一般是在入口处传入的(如 HTTP 入口或 Dubbo 服务入口),因此在链路中间再通过 ContextUtil.enter(xxx, origin)
传入可能不会生效。
Q: 很多开发通过错误码来处理流程,而非通过异常。这种写法,导致 Sentinel 不能拦截到异常,无法触发降级。对于这种情况,有没有什么好的处理方法?
A: 实际上 Sentinel 是通过 Tracer.trace(e)
来统计业务异常的,因此可以收到错误码就调用此函数来统计业务异常。
Q: 手动通过 SphU.entry(xxx)
进行埋点具有侵入性,有没有低侵入性的方案?
A: 可以利用 Sentinel 注解支持 或者 各种框架的适配。
Q: Sentinel 未来会考虑支持分布式链路调用跟踪吗?
A: Sentinel 的核心功能是流量控制和限流降级。分布式链路调用跟踪不是 Sentinel 关注的功能,可以参考其它分布式链路调用跟踪系统。
Q: Sentinel 支持集群限流吗?
A: 1.4.0 版本开始已经支持,可以参考 集群流控文档。
Q: Web 端的资源目前都是根据某个特定的 URL 限流,可不可以根据前缀匹配限流?
A: 对于 Sentinel Web Servlet Filter,可以借助 UrlCleaner
处理对应的 URL(如提取前缀的操作),这样对应的资源都会归到处理后的资源(如 /foo/1
和 /foo/2
都归到 /foo/*
资源里面)。UrlCleaner
实现 URL 前缀匹配只是个 trick,它会把对应的资源也给归一掉,直接在资源名粒度上实现模式匹配还是有很多顾虑的问题的。
A: 请参考以下步骤排查:
~/logs/csp/sentinel-record.log
查看 Token Server / Client 是否加载成功,是否成功启动;客户端规则和集群规则是否都接收成功;~/logs/csp/sentinel-cluster-client.log
日志,看一下是否是 Token Server 未启动或者规则未接收到的问题;Q: 通过 Sentinel 控制台或 API 来分配管理 Token Server 时,返回错误:token client/server mode not available: no SPI found
A: 请确保接入端引入了 Sentinel 集群流控相关的依赖(嵌入模式两者都需要):
sentinel-cluster-client-default
sentinel-cluster-server-default
更多信息可参见 集群流控文档。
Q: 集群流控规则中“单机均摊”阈值模式是什么意思?
A: 单机均摊模式下配置的阈值等同于单机能够承受的平均限额。Token Server 会根据客户端对应的 namespace(默认为 project.name
定义的应用名)下的连接数来计算总的阈值(比如独立模式下有 3 个 client 连接到了 token server,然后配的单机均摊阈值为 10,则计算出的集群总量就为 30)。单机均摊阈值仅用于计算总体阈值,不是说每台机器一定要控制在均摊阈值上。配置方式:若希望某个资源限制集群总量为 Q,服务实例为 N,则可以配置单机均摊阈值为 Q / N
。
Q: 集群流控 Token Server 中的 namespace set 有什么用处?
A: namespace set 即 Token Server 服务的作用域(命名空间集合),用于指定该 Token Server 可以为哪些应用提供集群流控服务,一般设置为接入端应用名的集合。Token Client 在连接到 token server 后会上报自己的命名空间(默认为 project.name
配置的应用名),token server 会根据上报的命名空间名称统计连接数。
default
,一般情况下不会用到Q:Sentinel Transport 同一台机器起相同的端口不报错?如果几个应用都没配 csp.sentinel.api.port
会出错吗?
A: 对于 sentinel-transport-simple-http
,默认 8719 端口被占用以后会自动选择下一个端口,直到有可用的端口为止。选择端口时间会比较长,本地如果起多个应用建议自己通过 csp.sentinel.api.port
设置端口。
Q: 为什么 Sentinel Transport 模块里自己用原生 Socket 或 Netty 自己实现的 HTTP Server,为什么不用 Web 容器(如 Tomcat)?
A: 使用 Web 容器作为一个组件来说太过于重量级了,因此我们自己实现了简单的 sentinel-transport-simple-http
和 sentinel-transport-netty-http
模块,两个模块的功能是相同的,一般用 sentinel-transport-simple-http
即可,而 sentinel-transport-netty-http
是为了后续的可扩展性和兼容性而设计的。
Q: 目前 Sentinel Transport 里面可否自己扩展添加 command?
A: 可以的,用户可以自行实现 CommandHandler
接口,并在实现类上加上 @CommandMapping
注解(代表 command name)。接着在资源目录下的 META-INF/services
目录下添加 com.alibaba.csp.sentinel.command.CommandHandler
文件(如果没有的话),在文件里加上自己的实现类的全名即可。比如:
package io.test;
@CommandMapping(name = "test")
public class TestCommandHandler implements CommandHandler<String> {
@Override
public CommandResponse<String> handle(CommandRequest request) {
return CommandResponse.ofSuccess("666");
}
}
在自己项目目录下的 resources/META-INF/services/com.alibaba.csp.sentinel.command.CommandHandler
文件中添加:
io.test.TestCommandHandler
这样初始化 Sentinel Transport Server 的时候,对应的 command 就会自动注册,可以通过 curl host:ip/test
来验证是否成功。
A: 在生产环境中使用 Sentinel 控制台需要考虑下面的问题:
详细指南请参考此 blog: 在生产环境中使用 Sentinel 控制台。
sentinel-dubbo-adapter
),然而在 Sentinel 控制台上没有找到我的应用?A: 请确保对应的依赖和参数配置正确。接入控制台需要上报的客户端依赖,如 sentinel-transport-simple-http
,不引入相关依赖则无法将相关信息上报到控制台。参数配置详情请参考 Sentinel 控制台文档。
详细的排查步骤请见下面。
A: Sentinel Dashboard 是一个单独启动的控制台,应用若想上报监控信息给 Sentinel 控制台,需要引入 Sentinel 上报信息的客户端。它们各自有自己的通信端口,其中控制台的端口可通过启动参数 -Dserver.port=xxxx
进行配置,而 Sentinel 客户端的端口可以通过启动参数 -Dcsp.sentinel.api.port
进行配置(默认是 8719)。两者都启动之后,Sentinel 客户端在首次访问资源时会初始化并给控制台发送心跳,之后控制台会通过客户端提供的端口对 Sentinel 客户端进行访问来拉取相关信息。基于此,接入控制台需要的步骤如下:
sentinel-transport-simple-http
-Dproject.name=xxxx
-Dcsp.sentinel.dashboard.server=ip:port
-Dcsp.sentinel.api.port=xxxx
(默认是 8719)curl http://ip:port/tree
命令查看调用链,正常情况下会显示出已访问资源的调用链。注意:Sentinel 会在客户端首次调用时候进行初始化,开始向控制台发送心跳包。因此需要确保客户端有访问量,才能在控制台上看到监控数据。另外,还是期待大家养成看日志的好习惯,详见 日志文档。
${user.home}/logs/csp/sentinel-dashboard.log
${user.home}/logs/csp/sentinel-record.log.xxx
常用排查问题列表:
~/logs/csp/sentinel-record.log
日志排查客户端发送心跳包是否正常,是否正常上报给 Dashboardcurl IP:port/getRules?type=flow
等命令查看结果,查看规则是否推送成功A: 请确保 Sentinel 控制台所在的机器时间与自己应用的机器时间保持一致(通过 NTP 等同步)。Sentinel 控制台是通过控制台所在机器的时间戳拉取监控数据的,因此时间不一致会导致拉不到实时的监控数据。
Q: 客户端成功接入控制台后,控制台配置规则准确无误,但是客户端收不到规则或者报错?比如配置的规则 resourceName 正确但却报 resourceName 为空的错误?
A: 排查客户端是否使用了低版本的 fastjson,低版本的 fastjson 可能会有此问题,建议使用和 Sentinel 相关组件一致版本的 fastjson。
Q: Sentinel 监控数据能保留多久?控制台聚合的统计数据可否进行持久化?
A: Sentinel 对监控数据的做法是定时落盘在客户端,然后 Sentinel 提供接口去拉取日志文件。所以 Sentinel 在监控数据上理论上是最少存储 1 天以上的数据;然而作为控制台展示,则仅在内存中聚合 5 分钟以内的统计数据,不进行持久化。
我们鼓励大家对 Dashboard 进行改造实现指标信息的持久化,并从其它的存储中(如 RDBMS、时序数据库等)拉取的监控信息,包括实时的和历史的数据。
Q: Sentinel 控制台有登录或者细粒度的权限控制功能吗?
A: 目前是没有的,权限控制功能需要自己去定制。
Q: Sentinel Dashboard 中簇点链路页面里面资源名称为什么会有重复的?
A: 最顶层的是 Context 名,用于区分不同调用链路(入口)。
Q: 应用已经退出了,Sentinel 控制台的应用列表里还有显示?
A: 若应用已退出,过 5 分钟没有收到心跳,控制台就会标记对应机器为失联状态,但不会将对应应用从列表中移除。
Q: 为什么说 Sentinel 控制台集群资源汇总仅支持 500 台以下的应用集群?
A: 因为 Sentinel 控制台仅作为示范,其监控聚合能力非常有限,但是应用端是没有限制的。若希望支持更多的机器,可以使用动态规则数据源并改造控制台;同时改造实现监控数据持久化。
Q: Sentinel 控制台规则配置里面“流控应用”是什么?
A: 对应规则中的 limitApp
,即请求来源,通过入口处 ContextUtil.enter(contextName, origin)
中的 origin
传入。参见上面的“按调用方进行限流”。
Q: 动态规则数据源分为哪几种?各自的使用场景?
A: 数据源分为只读的数据源和可写入的数据源。
WritableDataSource
写入到本地。A: 在控制台配置的规则是存在内存里面的,没有进行持久化,因此应用重启后规则就消失了。
可以参考 动态规则文档 持久化存储规则。
Q: 我在客户端处配置了动态规则数据源(如基于 ZooKeeper / Nacos / Apollo 的数据源),然后在控制台处向客户端推送了规则,但是规则并没有写入到对应的数据源中?
A: push 模式的数据源(如配置中心)都是只读的。对于配置中心类型的数据源(如 ZooKeeper),我们推荐在推送规则时直接推送至配置中心,然后配置中心再自动推送至所有的客户端(即 Dashboard -> Config Center -> Sentinel DataSource -> Sentinel
),目前需要自行改造控制台。可以参见:在生产环境中使用 Sentinel 控制台。
对于 pull 模式的数据源(如本地文件),则可以向 transport-common 模块的 WritableDataSourceRegistry
注册写入数据源,在推送规则时会一并推送至本地数据源中。
Q: 编译打包的时候 Maven 报错?
A: 请将 Maven 版本升级至较新版本(3.5.x)再进行构建。