Mastering Spring Alibaba Sentinel: Architecture, Flow Control, and Custom Error Handling
This tutorial walks through the core concepts of Spring Alibaba Sentinel, covering its architecture, resource and rule management, step‑by‑step integration into Spring Cloud projects, flow‑control configuration, custom exception handling with @SentinelResource, and advanced OpenFeign support, all illustrated with code snippets and diagrams.
Architecture Principles
Sentinel protects microservice stability by managing resources (HTTP requests, remote calls, methods) and rules (flow control, circuit breaking, system protection, hotspot parameters). Rules are defined in the Sentinel dashboard and stored in a configuration center such as Nacos or Zookeeper. Each microservice integrates a Sentinel client that receives rules from the console and applies them to resources.
Resources are any identifiable entry point (e.g., an HTTP endpoint /order/create or a method). Rules describe how Sentinel should limit or protect those resources.
Basic Integration with Spring Cloud
Integrating Sentinel into a Spring Cloud project involves three steps:
Download and start the Sentinel dashboard executable.
Add the Sentinel starter dependency to pom.xml:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>Configure Sentinel in application.yml (or application.properties) to point to the dashboard and enable eager loading:
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080
eager: true
feign:
sentinel:
enabled: trueStart the dashboard, for example:
java -Dserver.port=8080 -jar sentinel-dashboard-1.8.8.jarAdding Flow‑Control Rules
In the dashboard, navigate to the flow‑control rule page, select a resource such as /order/create, choose a threshold type (e.g., QPS), and set a limit (e.g., 1 QPS). Requests exceeding the limit are blocked by Sentinel.
Exception Handling
When a request violates a flow‑control rule, Sentinel throws a BlockException. For web endpoints, SentinelWebInterceptor (which extends AbstractSentinelInterceptor) intercepts the request, invokes SphU.entry, and triggers handleBlockException if blocked.
public class SentinelWebInterceptor extends AbstractSentinelInterceptor { ... }The default handler ( DefaultBlockExceptionHandler) returns HTTP 429 with a plain message. To customize the response, implement a custom BlockExceptionHandler:
@Component
public class OrderBlockExceptionHandler implements BlockExceptionHandler {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
String resourceName, BlockException e) throws Exception {
response.setContentType("application/json;charset=utf-8");
R error = R.error(500, resourceName + " was rate‑limited by Sentinel, reason: " + e.getClass());
String json = objectMapper.writeValueAsString(error);
PrintWriter out = response.getWriter();
out.print(json);
out.flush();
out.close();
}
}Annotate the business method with @SentinelResource and specify the blockHandler:
@SentinelResource(value = "createOrder", blockHandler = "createOrderBlockHandler")
public Order createOrder(Long userId, Long productId) { ... } public Order createOrderBlockHandler(Long userId, Long productId, BlockException e) {
Order order = new Order();
order.setId(0L);
order.setTotalAmount(BigDecimal.ZERO);
order.setUserId(userId);
order.setNickName("未知用户");
order.setAddress("异常信息:" + e.getClass());
return order;
}SentinelResource Internals
The annotation is defined in sentinel-core ( com.alibaba.csp.sentinel.annotation.SentinelResource) and processed by the aspect SentinelResourceAspect. The aspect calls SphU.entry to check rules and, on BlockException, invokes either a user‑defined blockHandler, a fallback, or the default fallback, finally re‑throwing the exception if none are provided.
public Object invokeResourceWithSentinel(ProceedingJoinPoint pjp) throws Throwable {
try {
entry = SphU.entry(resourceName, resourceType, entryType, pjp.getArgs());
return pjp.proceed();
} catch (BlockException ex) {
return handleBlockException(pjp, annotation, ex);
}
}OpenFeign Integration
Sentinel automatically wraps OpenFeign clients. The auto‑configuration class SentinelFeignAutoConfiguration provides a Feign.Builder that creates SentinelInvocationHandler. This handler performs SphU.entry before invoking the remote call and applies the configured fallback (if any) when a BlockException occurs.
public Object invoke(final Object proxy, final Method method, final Object[] args) {
try {
entry = SphU.entry(resourceName, EntryType.OUT, 1, args);
return methodHandler.invoke(args);
} catch (Throwable ex) {
if (fallbackFactory != null) {
Object fallbackResult = fallbackMethodMap.get(method)
.invoke(fallbackFactory.create(ex), args);
return fallbackResult;
}
throw ex;
}
}Thus, both HTTP endpoints and Feign calls share the same flow‑control and custom error‑handling mechanisms provided by Sentinel.
Sentinel‑based protection enables fine‑grained traffic control, circuit breaking, and hotspot parameter limiting for microservices, while offering extensible hooks for custom exception responses.
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.
