Implementing Traffic Governance and Circuit Breaking in Spring Cloud Applications with Alibaba Sentinel
Deploying the Sentinel Management Console
To visualize metrics and manage resilience policies, first provision the Sentinel dashboard. Fetch the latest executable JAR from the official repository.
java -Dserver.port=8858 -jar sentinel-dashboard-1.8.7.jar
Access the UI at http://localhost:8858. Authentication defaults to sentinel for both credentials. You can override these via JVM arguments:
-Dsentinel.dashboard.auth.username=<your_user>-Dsentinel.dashboard.auth.password=<your_pass>
Client Integration and Configuration
Import the Spring Cloud Alibaba starter to enable automatic wiring within your services:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.2.7.RELEASE</version>
</dependency>
Define the dashboard connectivity in your configuration file:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8858
eager: true
Note that the client registers itself asynchronously upon receiving its first request. Ensure at least one endpoint is hit to verify cluster communication.
Core Flow Control Mechanisms
Rule Matching Strategies
- Direct Match: Applies thresholds strictly against the targeted resource path.
- Associated Match: Monitors traffic on a correlated endpoint. If the linked resource breaches its limit, protection triggers for the current target.
- Chain Mode: Limits concurrency along a specific calling hierarchy. To instance, restricting calls originating from a gateway route before they reach downstream modules like inventory handlers.
Throttling Execution Modes
- Immediate Rejection (Default): Blocks requests instantly once the capacity cap is reached.
- Slow Start (Warm-up): Gradually ramps up allowed throughput over a defined cool-down period to prevent sudden load shocks.
- Fair Queuing: Requests exceeding the rate enter a waiting queue rather than failing immediately, ensuring orderly processing.
Hotspot Parameter Filtering
Sentinel supports granular control based on incoming method arguments. To activate this, specify the parameter index during rule creation. Remember that hotspot detection only functions when the target method is explicitly wrapped with @SentinelResource.
Resource Isolation and Circuit Breaking
Thread Pool Boundaries
In high-fanout architectures, such as API gateways dispatching hundreds of concurrent calls, isolating execution threads prevents cascade failures. Configure pool size limits via the console to cap parallelism safely.
Circuit Breaker Policies
The module offers three automatic recovery strategies:
- Latency Threshold: Evaluates response times over a rolling window. Example: If >5 slow requests occur within 10 seconds and >40% exceed 50ms latency, the circuit opens for 5 seconds.
- Error Rate Percentage: Trips when failed requests surpass a specified ratio within the statistical interval.
- Absolute Failure Count: Opens the circuit after reaching a hard limit of consecutive errors.
When activated, protected endpoints gracefully redirect to configured fallback methods instead of throwing unhandled exceptions.
Implementing Source-Based Access Controls
To restrict service access exclusively to trusted intermediaries (e.g., an API gateway), inject a custom identifier during routing and validate it upstream.
First, configure the gateway router to append a verification header:
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: user-backend
uri: lb://user-service
predicates:
- Path=/users/**
filters:
- AddRequestHeader=X-Verified-Source, trusted-gateway
default-filters:
- StripPrefix=1
Next, implement a resolver that extracts this identifier:
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
@Component
public class TrustedSourceResolver implements RequestOriginParser {
@Override
public String parseOrigin(@NonNull HttpServletRequest request) {
String sourceId = request.getHeader("X-Verified-Source");
return (sourceId != null && !sourceId.isBlank()) ? sourceId : "unverified";
}
}
Finally, register this source ID in the dashboard under Authorization Rules. Define whether it belongs to an allowlist or denylist to enforce strict perimeter security.
Handling Blocked Requests Gracefully
Intercept Sentinel block events and translate them into standardized HTTP payloads. Replace default stack traces with actionable feedback:
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@Component
public class StructuredBlockHandler implements BlockExceptionHandler {
private static final int RATE_LIMIT_STATUS = 429;
private static final int AUTH_REJECTION_STATUS = 401;
@Override
public void handle(HttpServletRequest req, HttpServletResponse resp, BlockException ex) throws IOException {
ResponsePayload payload = mapExceptionToPayload(ex);
resp.setContentType("application/json;charset=utf-8");
resp.setStatus(payload.statusCode());
String jsonResponse = String.format("{\"msg\":\"%s\",\"code\":%d}", payload.message(), payload.statusCode());
resp.getWriter().write(jsonResponse);
}
private ResponsePayload mapExceptionToPayload(BlockException e) {
if (e instanceof FlowException) {
return new ResponsePayload("Traffic threshold exceeded", RATE_LIMIT_STATUS);
} else if (e instanceof ParamFlowException) {
return new ResponsePayload("Parameter-level throttling applied", RATE_LIMIT_STATUS);
} else if (e instanceof DegradeException) {
return new ResponsePayload("Service degradation triggered", RATE_LIMIT_STATUS);
} else if (e instanceof AuthorityException) {
return new ResponsePayload("Access denied by authorization policy", AUTH_REJECTION_STATUS);
}
return new ResponsePayload("Internal system limitation encountered", RATE_LIMIT_STATUS);
}
record ResponsePayload(String message, int statusCode) {}
}