Understanding Sentinel's Slow Call Ratio Circuit Breaker Mechanism
Sentinel’s slow‑call‑ratio circuit breaker evaluates each request against a sliding‑window rule, opening when the proportion of slow calls exceeds the configured threshold and the minimum request count is met, then entering half‑open after the timeout, so proper window, count, and ratio settings are essential to avoid unexpected activations.
Sentinel is a flow‑control component for distributed service architectures, providing traffic control, circuit breaking, and adaptive system protection.
This article investigates why an online service occasionally triggered a circuit‑breaker for the "Ab" interface, despite the configured rule seemingly not being met.
Key findings:
Sentinel evaluates the slow‑call‑ratio rule on every request, not only after a sliding window completes.
The rule uses a sliding window (e.g., 3 s) with a single sub‑window to count total and slow requests.
If the slow‑call ratio exceeds the configured threshold (e.g., 50 %) and the total request count meets the minimum (e.g., 5), the circuit breaker opens for the configured duration.
After the open period, the breaker enters a half‑open state, allowing one probe request to decide whether to close or reopen.
The implementation details are explored through the following code snippets:
@SentinelResource(value = "pandora.abService.callAb", blockHandler = "callAb", blockHandlerClass = SentinelFallbackHandler.class)
public String callAb(Long userId, String key) {
//省略...
} @Bean
@ConditionalOnMissingBean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
} private Entry entryWithPriority(ResourceWrapper resourceWrapper, int count, boolean prioritized, Object... args) throws BlockException {
Context context = ContextUtil.getContext();
//省略...
ProcessorSlot
chain = lookProcessChain(resourceWrapper);
//省略...
new CtEntry(resourceWrapper, chain, context);
try {
chain.entry(context, resourceWrapper, null, count, prioritized, args);
} catch (BlockException e1) {
e.exit(count, args);
throw e1;
} catch (Throwable e1) {
RecordLog.info("Sentinel unexpected exception", e1);
}
return e;
} public void entry(Context context, ResourceWrapper resourceWrapper, DefaultNode node, int count,
boolean prioritized, Object... args) throws Throwable {
try {
fireEntry(context, resourceWrapper, node, count, prioritized, args);
node.increaseThreadNum();
node.addPassRequest(count);
} catch (BlockException e) {
context.getCurEntry().setBlockError(e);
node.increaseBlockQps(count);
if (context.getCurEntry().getOriginNode() != null) {
context.getCurEntry().getOriginNode().increaseBlockQps(count);
}
throw e;
} catch (Throwable e) {
context.getCurEntry().setError(e);
throw e;
}
} public void exit(Context context, ResourceWrapper r, int count, Object... args) {
Entry curEntry = context.getCurEntry();
if (curEntry.getBlockError() == null) {
for (CircuitBreaker circuitBreaker : circuitBreakers) {
circuitBreaker.onRequestComplete(context);
}
}
fireExit(context, r, count, args);
}These snippets illustrate the responsibility‑chain pattern used by Sentinel, the StatisticSlot that records pass/block counts, and the DegradeSlot that performs slow‑call‑ratio evaluation and state transitions (CLOSED → OPEN → HALF‑OPEN).
Conclusion: Sentinel’s slow‑call‑ratio circuit‑breaker can trigger early, based on per‑request evaluation within the sliding window. Properly configuring the rule (window length, minimum request count, ratio threshold) and understanding the chain of slots helps diagnose and prevent unexpected circuit‑breaker activations.
DeWu Technology
A platform for sharing and discussing tech knowledge, guiding you toward the cloud of technology.
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.