Sync Sentinel Flow Rules with Apollo for Persistent Configuration
This tutorial explains the limitation of Sentinel Dashboard rule persistence, analyzes the data flow, and provides a step‑by‑step solution using DynamicRuleProvider and DynamicRulePublisher to read and write flow rules in Apollo, complete with code examples and configuration details.
Problem Analysis
In previous tutorials we stored Sentinel rate‑limiting rules in Nacos and Apollo, but the rules could only be modified through the Nacos or Apollo UI to achieve persistence; changes made in the Sentinel Dashboard were not saved back to the configuration center, and the JSON format became hard to read as the number of rules grew.
The data flow diagram shows two update paths: Blue arrow – rule updates initiated by the configuration center. Orange arrow – rule updates initiated by the Sentinel Dashboard.
Both paths allow Sentinel Dashboard to read the latest rules, but there is no mechanism to push those updates back to the configuration center.
Solution Overview
To configure cluster flow control rules via the Sentinel console, the console must be adapted. Interfaces for pushing and pulling rules to a remote configuration center are provided. Since Sentinel 1.4.0 we have: DynamicRuleProvider – fetch rules. DynamicRulePublisher – push rules. For cluster flow control each rule needs a unique flowId, so we recommend managing all rules through a dynamic rule source and generating flowIds centrally.
By implementing these two interfaces for Apollo, we can synchronize rule modifications made in the Sentinel Dashboard with Apollo storage.
Implementation Steps
Step 1 : Modify pom.xml to uncomment the Apollo OpenAPI dependency.
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-openapi</artifactId>
<version>1.2.0</version>
<!--<scope>test</scope>-->
</dependency>Step 2 : Update the sidebar HTML to point to the new flow‑rule page.
<li ui-sref-active="active">
<a ui-sref="dashboard.flow({app: entry.app})">
<i class="glyphicon glyphicon-filter"></i> 流控规则
</a>
</li>Step 3 : Create a new apollo package under com.alibaba.csp.sentinel.dashboard.rule for Apollo extensions.
Step 4 : Define an Apollo configuration class that sets the portal URL and token.
@Configuration
public class ApolloConfig {
// beans for converters
}Step 5 : Implement the rule‑fetching provider.
@Component("flowRuleApolloProvider")
public class FlowRuleApolloProvider implements DynamicRuleProvider<List<FlowRuleEntity>> {
@Autowired private ApolloOpenApiClient apolloOpenApiClient;
@Autowired private Converter<String, List<FlowRuleEntity>> converter;
@Value("${env:DEV}") private String env;
@Override
public List<FlowRuleEntity> getRules(String appName) throws Exception {
String flowDataId = "sentinel.flowRules";
OpenNamespaceDTO ns = apolloOpenApiClient.getNamespace(appName, env, "default", "application");
String rules = ns.getItems().stream()
.filter(p -> p.getKey().equals(flowDataId))
.map(OpenItemDTO::getValue)
.findFirst().orElse("");
if (StringUtil.isEmpty(rules)) return new ArrayList<>();
return converter.convert(rules);
}
}Step 6 : Implement the rule‑publishing component.
@Component("flowRuleApolloPublisher")
public class FlowRuleApolloPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {
@Autowired private ApolloOpenApiClient apolloOpenApiClient;
@Autowired private Converter<List<FlowRuleEntity>, String> converter;
@Value("${env:DEV}") private String env;
@Override
public void publish(String app, List<FlowRuleEntity> rules) throws Exception {
String flowDataId = "sentinel.flowRules";
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) return;
OpenItemDTO item = new OpenItemDTO();
item.setKey(flowDataId);
item.setValue(converter.convert(rules));
item.setComment("modify by sentinel-dashboard");
item.setDataChangeCreatedBy("apollo");
apolloOpenApiClient.createOrUpdateItem(app, env, "default", "application", item);
NamespaceReleaseDTO release = new NamespaceReleaseDTO();
release.setEmergencyPublish(true);
release.setReleaseComment("release by sentinel-dashboard");
release.setReleasedBy("apollo");
release.setReleaseTitle("release by sentinel-dashboard");
apolloOpenApiClient.publishNamespace(app, env, "default", "application", release);
}
}Step 7 : Inject the new provider and publisher beans into FlowControllerV2 using @Qualifier annotations.
@Autowired @Qualifier("flowRuleApolloProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired @Qualifier("flowRuleApolloPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;Code Example Repository
The complete source code can be found in the alibaba-sentinel-dashboard-apollo project on GitHub and Gitee.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
