Cloud Native 11 min read

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.

Programmer DD
Programmer DD
Programmer DD
Sync Sentinel Flow Rules with Apollo for Persistent Configuration

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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

SentinelApollospring-bootflow-control
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.