Skip to content

使用指南

Peihao Yang edited this page Mar 2, 2022 · 11 revisions

Sentinel 的设计采用了责任链的模式,用户指定的各类规则会自动通过 base::SlotChain 上的插槽 (Slot) 进行检测。用户使用 Sentinel Rust (后文均用 Sentinel 表示 Sentinel Rust) ,主要需要以下几步:

  1. 在项目配置中添加依赖,对 Sentinel 的运行环境进行相关配置并初始化。
  2. 埋点(定义资源),确定系统中有哪些资源需要防护。
  3. 配置规则,为每个资源配置具体的规则,规则的配置方法可参考各个模块的使用文档。
  4. 编写资源防护的入口和出口代码。

添加依赖

首先需要在项目中添加 Sentinel 依赖,向 Cargo.toml 中添加

[dependencies]
sentinel-rs = { version = "0.1.0", features = ["full"] }

可选 features 列表:

  • macro:过程宏支持,简化定义资源的步骤,参考 macro 示例
  • async:支持异步资源,参考 tokio 示例
  • exporter:支持向 prometheus 导出监控数据,参考 Prometheus 示例配置Sentinel Prometheus Metrics 定义
  • logger_env: 使用内置 env_logger 初始化日志输出。
  • logger_log4rs: 使用内置 log4rs 初始化日志输出。
  • ds_consul: 使用 Consul 动态配置规则。
  • ds_etcdv3:使用 etcd 动态配置规则。
  • ds_k8s:使用 k8s 动态配置规则。
  • metric_log: 存储指定规模的监控数据格式化文本记录。若仅出于监控目的,推荐使用 Prometheus 进行可视化监控,配合 Grafana 等平台使用。

通用配置及初始化

使用 Sentinel 需要在应用启动时对 Sentinel 运行环境进行相关配置并触发初始化。api 下提供如下函数:

  • init_default():从环境变量指定的配置文件以及环境变量中读取相应配置来初始化 Sentinel,若环境变量不存在则使用默认值。
  • init_with_config_file(config_path: &mut String):从给定的 YAML 文件中读取相应配置来初始化 Sentinel,参考 文件配置示例。。
  • init_with_config(config_entity: ConfigEntity): 用户硬编码配置对象ConfigEntity来初始化 Sentinel,参考 硬编码配置示例。。

通用配置项加载策略和配置项请参考通用配置章节

示例代码:

use sentinel_rs::{init_default, logging};
init_default().unwrap_or_else(|err| logging::error!("{:?}", err));

注意:必须成功调用 Sentinel 的初始化函数以后再调用埋点 API。

埋点(定义资源)

使用 Sentinel 的 Entry API 将业务逻辑封装起来,这一步称为“埋点”。每个埋点都有一个资源名称(resource),代表触发了这个资源的调用或访问。

埋点 API 位于 api 中,通过构造 EntryBuilder,调用它的方法 build() 创建 Entry。 EntryBuilder 提供了链式的传参方式,未传入的参数将使用默认构造。

目前 EntryBuilder 具有以下的埋点配置方法传递参数:

  • fn with_resource_type(mut self, resource_type: ResourceType) -> Self:标记该埋点资源的流量类型,其中 ResourceType::Inbound 代表入口流量,ResourceType::Outbound 代表出口流量。若不指定,默认为 Outbound。
  • fn with_traffic_type(mut self, traffic_type: TrafficType) -> Self:标记该埋点资源的分类。
  • fn with_batch_count(mut self, batch_count: u32) -> Self:标记每次触发该埋点计为几次调用。若不指定,默认为 1。
  • fn with_slot_chain(mut self, slot_chain: Arc<SlotChain>) -> Self:埋点执行的检查的 SlotChain,若不指定,默认使用全局 SlotChain
  • fn with_flag(mut self, flag: i32) -> Self:埋点携带的参数,为热点参数统计预留。
  • pub fn with_args(mut self, args: Option<ParamsList>) -> Self:埋点携带的参数列表,为热点参数统计预留。
  • fn with_attachments(mut self, attachments: Option<ParamsMap>) -> Self:埋点携带的参数表,为热点参数统计预留。

埋点 API 示例:

use sentinel_rs::base;
use sentinel_rs::api::EntryBuilder;

let entry_builder = EntryBuilder::new(res_name.clone())
	.with_traffic_type(base::TrafficType::Inbound);
if let Ok(entry) = entry_builder.build() {
	// 请求可以通过,在此处编写您的业务逻辑
	// 务必保证业务逻辑结束后 exit()
    entry.borrow().exit()
} else {
	// 请求被流控,可以从 BlockError 中获取限流详情
	// block 后不需要进行 exit()
}

若该次调用被拒绝,则 build() 会返回 Result 代表被 Sentinel 限流。BlockError 提供了限流原因以及触发的规则等信息,可以方便开发者获取相关信息进行记录和处理。

规则配置

API 硬编码方式

Sentinel 支持原始的硬编码方式加载规则,可以通过各个模块的 load_rules()append_rules() 函数加载规则,前者会覆盖之前的规则设置,后者只会向设置中追加规则。目前的版本中,这也是对单一资源加载多条规则的唯一手段。以流控规则为例:

flow::load_rules(vec![Arc::new(flow::Rule {
    resource: "example".into(),
    threshold: 10.0,
    calculate_strategy: flow::CalculateStrategy::Direct,
    control_strategy: flow::ControlStrategy::Reject,
    ..Default::default()
})]);

标签宏硬编码方式

Sentinel 提供了易用的标签宏,可以帮助用户快速上手规则配置,我们为不同策略提供了丰富的标签宏使用 示例,也可以阅读后续文档了解。下面以流控规则为例

#[flow(threshold=10.0, calculate_strategy=Direct)]
pub fn task() -> u32 {}

在上面的例子中,标签宏会修改 task 函数签名,返回 Result<u32, String>。接着,它将自动向规则列表中追加规则,调用 EntryBuilder 创建 Sentinel Entry,检查指定的规则。如果该任务成功执行,会返回 Ok(u32) 类型的返回值;否则会返回 Err(String) 类型的限流原因和触发限流的参数。

需要注意,当前的标签宏实现,仅支持在 Resource 上指定单一规则。

动态数据源

支持动态加载 Sentinel 规则,参考