Sentinel Parameter Flow Control provides functionality of flow control by frequent (hot spot) parameters.
—
Exception handling for when parameter flow control is triggered. ParamFlowException provides detailed information about which parameter caused the flow control, enabling precise error handling and monitoring in applications.
Creates parameter flow exceptions with resource and parameter information.
/**
* Create parameter flow exception with resource name and parameter value
* @param resourceName the resource that triggered flow control
* @param param the parameter value that caused the trigger
*/
public ParamFlowException(String resourceName, String param);
/**
* Create parameter flow exception with resource, parameter, and rule information
* @param resourceName the resource that triggered flow control
* @param param the parameter value that caused the trigger
* @param rule the rule that was triggered
*/
public ParamFlowException(String resourceName, String param, ParamFlowRule rule);
/**
* Create parameter flow exception with message and cause
* @param resourceName the resource name
* @param message the exception message
* @param cause the underlying cause
*/
public ParamFlowException(String resourceName, String message, Throwable cause);Usage Example:
// Exceptions are typically thrown by Sentinel automatically
try {
Entry entry = SphU.entry("userService", EntryType.IN, 1, "VIP_USER");
// ... business logic
} catch (ParamFlowException ex) {
// Handle parameter flow control exception
System.out.println("Resource: " + ex.getResourceName());
System.out.println("Parameter: " + ex.getLimitParam());
System.out.println("Rule: " + ex.getRule());
}Provides information about the resource that triggered the parameter flow control.
/**
* Get the resource name that triggered the parameter flow control
* @return resource name
*/
public String getResourceName();Usage Example:
try {
processUserRequest("high_frequency_user");
} catch (ParamFlowException ex) {
String resource = ex.getResourceName();
// Log with resource context
logger.warn("Parameter flow control triggered for resource: {}", resource);
// Resource-specific handling
if ("userService".equals(resource)) {
handleUserServiceFlowControl(ex);
} else if ("productService".equals(resource)) {
handleProductServiceFlowControl(ex);
}
}Provides the specific parameter value that caused the flow control to trigger.
/**
* Get the parameter value that triggered the parameter flow control
* @return the parameter value
*/
public String getLimitParam();Usage Example:
try {
processUserData(userId, productId);
} catch (ParamFlowException ex) {
String limitParam = ex.getLimitParam();
// Log the specific parameter that caused the issue
logger.warn("Flow control triggered by parameter: {}", limitParam);
// Parameter-specific handling
if (limitParam.startsWith("VIP_")) {
// Handle VIP user flow control
notifyVipSupport(limitParam);
} else if (limitParam.matches("\\d+")) {
// Handle numeric parameter (e.g., product ID)
handleProductFlowControl(limitParam);
}
}Provides access to the specific rule that was triggered.
/**
* Get triggered rule.
* Note: the rule result is a reference to rule map and SHOULD NOT be modified.
* @return triggered rule
*/
public ParamFlowRule getRule();Usage Example:
try {
performOperation(userId);
} catch (ParamFlowException ex) {
ParamFlowRule rule = ex.getRule();
if (rule != null) {
// Access rule details for better error handling
int paramIdx = rule.getParamIdx();
double count = rule.getCount();
int grade = rule.getGrade();
logger.warn("Parameter flow control: resource={}, param={}, " +
"paramIdx={}, count={}, grade={}",
ex.getResourceName(), ex.getLimitParam(),
paramIdx, count, grade);
// Rule-specific handling
if (rule.getGrade() == RuleConstant.FLOW_GRADE_QPS) {
handleQpsFlowControl(ex, rule);
} else if (rule.getGrade() == RuleConstant.FLOW_GRADE_THREAD) {
handleThreadFlowControl(ex, rule);
}
}
}import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
public void processUserRequest(String userId) {
Entry entry = null;
try {
entry = SphU.entry("userService", EntryType.IN, 1, userId);
// Your business logic here
performUserOperation(userId);
} catch (ParamFlowException ex) {
// Handle parameter flow control
logger.warn("User {} hit flow control limit", ex.getLimitParam());
throw new ServiceException("Service temporarily unavailable for user: " + userId);
} catch (BlockException ex) {
// Handle other types of flow control
logger.warn("General flow control triggered for resource: {}", ex.getResourceName());
throw new ServiceException("Service temporarily unavailable");
} finally {
if (entry != null) {
entry.exit();
}
}
}private final Counter paramFlowControlCounter = Counter.build()
.name("param_flow_control_total")
.help("Parameter flow control triggered count")
.labelNames("resource", "parameter")
.register();
public void processWithMetrics(String resourceName, Object... params) {
Entry entry = null;
try {
entry = SphU.entry(resourceName, EntryType.IN, 1, params);
// Business logic
doBusinessLogic(params);
} catch (ParamFlowException ex) {
// Record metrics
paramFlowControlCounter.labels(ex.getResourceName(), ex.getLimitParam()).inc();
// Detailed logging
ParamFlowRule rule = ex.getRule();
if (rule != null) {
logger.warn("Parameter flow control triggered: " +
"resource={}, parameter={}, limit={}, grade={}",
ex.getResourceName(), ex.getLimitParam(),
rule.getCount(), rule.getGrade());
}
// Business-specific handling
handleParameterFlowControl(ex);
} finally {
if (entry != null) {
entry.exit();
}
}
}
private void handleParameterFlowControl(ParamFlowException ex) {
String param = ex.getLimitParam();
String resource = ex.getResourceName();
// Notify monitoring systems
alertingService.sendAlert("Parameter flow control",
"Resource: " + resource + ", Parameter: " + param);
// Implement fallback logic
if ("userService".equals(resource)) {
// Redirect to fallback user service
fallbackUserService.processUser(param);
}
}import java.util.concurrent.TimeUnit;
public void processWithRetry(String userId, int maxRetries) {
int attempts = 0;
while (attempts < maxRetries) {
Entry entry = null;
try {
entry = SphU.entry("userService", EntryType.IN, 1, userId);
// Business logic
performUserOperation(userId);
return; // Success, exit retry loop
} catch (ParamFlowException ex) {
attempts++;
logger.warn("Parameter flow control attempt {}/{}: user={}, rule={}",
attempts, maxRetries, ex.getLimitParam(),
ex.getRule() != null ? ex.getRule().getCount() : "unknown");
if (attempts >= maxRetries) {
// Max retries reached
logger.error("Max retries reached for user: {}", userId);
throw new ServiceException("Service unavailable after retries", ex);
}
// Wait before retry with exponential backoff
try {
TimeUnit.MILLISECONDS.sleep(100 * attempts);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new ServiceException("Interrupted during retry", e);
}
} finally {
if (entry != null) {
entry.exit();
}
}
}
}ParamFlowException extends BlockException and has the following characteristics:
fillInStackTrace() to return this for performancegetResourceName()getLimitParam() (alias for getMessage())getRule() when exception includes rule informationentry.exit() is calledgetRule() should not be modifiedInstall with Tessl CLI
npx tessl i tessl/maven-sentinel-parameter-flow-control