CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-sentinel-parameter-flow-control

Sentinel Parameter Flow Control provides functionality of flow control by frequent (hot spot) parameters.

Pending
Overview
Eval results
Files

flow-control-exceptions.mddocs/

Flow Control Exceptions

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.

Capabilities

Basic Exception Creation

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());
}

Resource Information

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);
    }
}

Parameter Information

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);
    }
}

Rule Information

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);
        }
    }
}

Exception Handling Patterns

Basic Exception Handling

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();
        }
    }
}

Advanced Exception Handling with Metrics

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);
    }
}

Exception Handling with Retry Logic

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();
            }
        }
    }
}

Exception Properties

ParamFlowException extends BlockException and has the following characteristics:

  • Stack trace: Overrides fillInStackTrace() to return this for performance
  • Resource name: Always available through getResourceName()
  • Parameter value: Available through getLimitParam() (alias for getMessage())
  • Rule reference: Available through getRule() when exception includes rule information
  • Thread safety: Immutable once created, safe for concurrent access

Best Practices

  1. Always handle in finally blocks: Use try-finally to ensure entry.exit() is called
  2. Log parameter information: Include both resource and parameter in logs for debugging
  3. Implement fallback logic: Provide alternative processing paths when flow control triggers
  4. Monitor exception patterns: Track which parameters frequently trigger flow control
  5. Don't modify rule references: The rule returned by getRule() should not be modified

Install with Tessl CLI

npx tessl i tessl/maven-sentinel-parameter-flow-control

docs

cluster-mode.md

exception-items.md

flow-control-exceptions.md

index.md

parameter-flow-rules.md

rule-management.md

tile.json