Dynamic Rule Configuration and DataSource Extensions in Sentinel
Sentinel treats resource definition as the primary developer concern. Once resources are defined, flow control and circuit breaker rules can be attached dynamically. Two core mechanisms exist for rule updates:
Direct API manipulation through dedicated manager classes:
FlowRuleManager.loadRules(List<FlowRule> flowRules);
DegradeRuleManager.loadRules(List<DegradeRule> degradeRules);
Hard-coding rules via these APIs works for prototyping, yet production deployments require externalized, dynamic rule sources.
DataSource Integration Architecture
Because loadRules() only accepts in-memory collections, Sentinel exposes the DataSource interface to bridge arbitrary external stores. The recommended architecture involves publishing rules from the management console to a cetnralized configuration server, while application nodes implement ReadableDataSource to consume changes.
Two interaction models dominate:
- Polling (Pull): Clients periodically fetch configurations from a backend store such as a relational database, flat file, or version control system. Implementation is straightforward, though change detection carries inherent latency.
- Push: The configuration server broadcasts updates to subscribed clients. Implementations built on Nacos, ZooKeeper, or similar registries provide stronger consistency guarantees and near-real-time propagation.
Supported integrations include:
- Pull-based: File polling, Consul, Eureka
- Push-based: Nacos, ZooKeeper, Apollo, etcd, Redis
Implementing Pull-Based Sources
Polling data sources typically extend AutoRefreshDataSource. Subclasses implement readSource() to return configuration payloads as strings from the target back end. The framework handles scheduling and automatic refreshing.
Implementing Push-Based Sources
For event-driven updates, extend AbstractDataSource. Register a change listener inside the constructor, then implement readSource() to fetch the current configuration string. Production setups often require console modifications to push application-scoped rules directly to the configuration server.
Registering Configuration Sources
After instantiation, bind a data source to its rule manager:
ReadableDataSource<String, List<FlowRule>> flowSource = new NacosDataSource<>(serverAddr, configGroup, dataKey, parser);
FlowRuleManager.register2Property(flowSource.getProperty());
To eliminate manual registration, leverage Santinel's InitFunc SPI. Create an implementation that wires up data sources inside the init() method:
package com.example.sentinel.bootstrap;
public class RuleDataSourceInitializer implements InitFunc {
@Override
public void init() {
String serverAddr = "localhost:8848";
String configGroup = "sentinel:flow";
String dataKey = "demo-service.flow.rules";
ReadableDataSource<String, List<FlowRule>> flowSource = new NacosDataSource<>(
serverAddr,
configGroup,
dataKey,
config -> com.alibaba.fastjson.JSON.parseObject(config, new com.alibaba.fastjson.TypeReference<List<FlowRule>>() {})
);
FlowRuleManager.register2Property(flowSource.getProperty());
}
}
Enable automatic discovery by adding the fully-qualified class name to META-INF/services/com.alibaba.csp.sentinel.init.InitFunc:
com.example.sentinel.bootstrap.RuleDataSourceInitializer
Sentinel triggers this initialization on the first access to any guarded resource.
Practical Examples
Client API Approach
The Sentinel Dashboard can inspect and mutate in-memory rules through the built-in rule APIs. To expose these endpoints, include:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>x.y.z</version>
</dependency>
File-Based Polling Source
FileRefreshableDataSource demonstrates a simple polling implementation that monitors a local file for modifications and reloads rules accordingly. Required dependency:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-extension</artifactId>
<version>x.y.z</version>
</dependency>
Nacos Push Source
Nacos serves as both a service registry and configuration server. Sentinel's Nacos adapter enables rule distribution through configuration keys.
Dependency:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>x.y.z</version>
</dependency>
Integration code:
ReadableDataSource<String, List<FlowRule>> nacosSource = new NacosDataSource<>(
nacosServer,
ruleGroup,
ruleDataId,
payload -> JSON.parseObject(payload, new TypeReference<List<FlowRule>>() {})
);
FlowRuleManager.register2Property(nacosSource.getProperty());
Additional connection properties, such as authentication credentials, can be supplied through an overloaded constructor accepting Properties.
Reference implementation: sentinel-demo-nacos-datasource.
ZooKeeper Push Source
Sentinel provides a ZooKeeper adapter for rule storage.
Dependency:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-zookeeper</artifactId>
<version>x.y.z</version>
</dependency>
Integration code:
ReadableDataSource<String, List<FlowRule>> zkSource = new ZookeeperDataSource<>(
zkHosts,
rulePath,
payload -> JSON.parseObject(payload, new TypeReference<List<FlowRule>>() {})
);
FlowRuleManager.register2Property(zkSource.getProperty());
Reference implementation: sentinel-demo-zookeeper-datasource.
Apollo Push Source
Apollo configuration center integration follows the same pattern.
Dependency:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-apollo</artifactId>
<version>x.y.z</version>
</dependency>
Integration code:
ReadableDataSource<String, List<FlowRule>> apolloSource = new ApolloDataSource<>(
appNamespace,
ruleKey,
fallbackRules,
payload -> JSON.parseObject(payload, new TypeReference<List<FlowRule>>() {})
);
FlowRuleManager.register2Property(apolloSource.getProperty());
The fallback rule list activates when Apollo is unreachable.
Reference implementation: sentinel-demo-apollo-datasource.
Redis Push Source
Sentinel also supports Redis as a configuration backend (JDK 8+ required).
Dependency:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-redis</artifactId>
<version>x.y.z</version>
</dependency>