CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-eclipse-jetty-ee10--jetty-ee10-servlets

Collection of utility servlets and filters for Jakarta EE 10 web applications including CORS, DoS protection, QoS management, header manipulation, and server-sent events.

Pending
Overview
Eval results
Files

quality-of-service.mddocs/

Quality of Service Management

⚠️ DEPRECATED: This filter is deprecated. Use org.eclipse.jetty.server.handler.QoSHandler instead.

Quality of Service filter for limiting concurrent requests with priority-based queuing and suspension. This filter helps manage server resources by controlling the number of simultaneous requests being processed.

Capabilities

QoSFilter

Filter for managing request concurrency and quality of service.

/**
 * Quality of Service filter for limiting concurrent requests.
 * Provides priority-based queuing and request suspension capabilities.
 */
public class QoSFilter implements Filter {
    /**
     * Initialize the filter with configuration parameters
     * @param filterConfig Filter configuration
     */
    public void init(FilterConfig filterConfig);
    
    /**
     * Process requests with QoS management
     * @param request The servlet request
     * @param response The servlet response
     * @param chain The filter chain
     * @throws IOException if I/O error occurs
     * @throws ServletException if servlet error occurs
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
        throws IOException, ServletException;
    
    /**
     * Clean up filter resources  
     */
    public void destroy();
    
    /**
     * Get the wait time before request suspension
     * @return Wait time in milliseconds
     */
    public long getWaitMs();
    
    /**
     * Get the suspension timeout period
     * @return Suspension timeout in milliseconds
     */
    public long getSuspendMs();
    
    /**
     * Get the maximum number of concurrent requests allowed
     * @return Maximum concurrent requests
     */
    public int getMaxRequests();
    
    /**
     * Get the priority of the given request (for subclass extension)
     * @param request The servlet request
     * @return Priority level (higher numbers = higher priority)
     */
    protected int getPriority(ServletRequest request);
}

Configuration Constants

Parameter name constants for filter configuration.

public static final String MANAGED_ATTR_INIT_PARAM = "managedAttr";
public static final String MAX_REQUESTS_INIT_PARAM = "maxRequests";
public static final String MAX_PRIORITY_INIT_PARAM = "maxPriority";
public static final String MAX_WAIT_INIT_PARAM = "waitMs";
public static final String SUSPEND_INIT_PARAM = "suspendMs";

Configuration Parameters

maxRequests

Type: Integer
Default: 10
Description: Maximum number of requests that can be processed concurrently.

maxPriority

Type: Integer
Default: 10
Description: Maximum priority level for request prioritization.

waitMs

Type: Long
Default: 50
Description: Time in milliseconds to wait before suspending a request when max concurrent requests is reached.

suspendMs

Type: Long
Default: -1 (container default)
Description: Timeout in milliseconds for suspended requests. -1 uses container default timeout.

managedAttr

Type: Boolean
Default: false
Description: Whether to register the filter as a managed attribute in the ServletContext.

Usage Examples

Basic QoS Configuration

<!-- Web.xml configuration -->
<filter>
    <filter-name>QoSFilter</filter-name>
    <filter-class>org.eclipse.jetty.ee10.servlets.QoSFilter</filter-class>
    <init-param>
        <param-name>maxRequests</param-name>
        <param-value>20</param-value>
    </init-param>
    <init-param>
        <param-name>waitMs</param-name>
        <param-value>100</param-value>
    </init-param>
    <init-param>
        <param-name>suspendMs</param-name>
        <param-value>30000</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>QoSFilter</filter-name>
    <url-pattern>/api/*</url-pattern>
</filter-mapping>

High-Capacity Configuration

<filter>
    <filter-name>HighCapacityQoS</filter-name>
    <filter-class>org.eclipse.jetty.ee10.servlets.QoSFilter</filter-class>
    <init-param>
        <param-name>maxRequests</param-name>
        <param-value>100</param-value>
    </init-param>
    <init-param>
        <param-name>waitMs</param-name>
        <param-value>25</param-value>
    </init-param>
    <init-param>
        <param-name>suspendMs</param-name>
        <param-value>60000</param-value>
    </init-param>
    <init-param>
        <param-name>maxPriority</param-name>
        <param-value>20</param-value>
    </init-param>
</filter>

Conservative QoS Configuration

<!-- For resource-constrained environments -->
<filter>
    <filter-name>ConservativeQoS</filter-name>
    <filter-class>org.eclipse.jetty.ee10.servlets.QoSFilter</filter-class>
    <init-param>
        <param-name>maxRequests</param-name>
        <param-value>5</param-value>
    </init-param>
    <init-param>
        <param-name>waitMs</param-name>
        <param-value>200</param-value>
    </init-param>
    <init-param>
        <param-name>suspendMs</param-name>
        <param-value>10000</param-value>
    </init-param>
</filter>

Managed Attribute Configuration

<!-- Enable JMX management -->
<filter>
    <filter-name>ManagedQoSFilter</filter-name>
    <filter-class>org.eclipse.jetty.ee10.servlets.QoSFilter</filter-class>
    <init-param>
        <param-name>maxRequests</param-name>
        <param-value>50</param-value>
    </init-param>
    <init-param>
        <param-name>managedAttr</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

Custom Priority QoS Filter

import org.eclipse.jetty.ee10.servlets.QoSFilter;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.http.HttpServletRequest;

/**
 * Custom QoS filter that prioritizes requests based on user roles
 */
public class PriorityQoSFilter extends QoSFilter {
    @Override
    protected int getPriority(ServletRequest request) {
        if (request instanceof HttpServletRequest) {
            HttpServletRequest httpRequest = (HttpServletRequest) request;
            
            // Check user role for priority
            String userRole = getUserRole(httpRequest);
            
            switch (userRole) {
                case "ADMIN":
                    return 10; // Highest priority
                case "PREMIUM":
                    return 7;  // High priority
                case "USER": 
                    return 5;  // Normal priority
                case "GUEST":
                    return 2;  // Low priority  
                default:
                    return 1;  // Lowest priority
            }
        }
        
        return super.getPriority(request);
    }
    
    private String getUserRole(HttpServletRequest request) {
        // Implementation-specific role extraction
        // Could check session, JWT token, headers, etc.
        String authHeader = request.getHeader("Authorization");
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            return JwtUtils.extractRole(authHeader.substring(7));
        }
        
        return "GUEST";
    }
}

API Endpoint Priority Filter

/**
 * QoS filter that prioritizes based on API endpoint criticality
 */
public class ApiPriorityQoSFilter extends QoSFilter {
    @Override
    protected int getPriority(ServletRequest request) {
        if (request instanceof HttpServletRequest) {
            HttpServletRequest httpRequest = (HttpServletRequest) request;
            String path = httpRequest.getRequestURI();
            
            // Critical system endpoints get highest priority
            if (path.startsWith("/api/health") || path.startsWith("/api/status")) {
                return 10;
            }
            
            // Admin endpoints get high priority
            if (path.startsWith("/api/admin")) {
                return 8;
            }
            
            // User management gets medium-high priority
            if (path.startsWith("/api/user") || path.startsWith("/api/auth")) {
                return 6;
            }
            
            // Data endpoints get medium priority
            if (path.startsWith("/api/data")) {
                return 5;
            }
            
            // Reporting endpoints get lower priority
            if (path.startsWith("/api/reports")) {
                return 3;
            }
            
            // All other endpoints get default priority
            return 4;
        }
        
        return super.getPriority(request);
    }
}

Programmatic Configuration

import org.eclipse.jetty.ee10.servlets.QoSFilter;
import jakarta.servlet.FilterRegistration;
import jakarta.servlet.ServletContext;

public class QoSConfig {
    public static void configureQoSFilter(ServletContext context) {
        FilterRegistration.Dynamic qosFilter = context.addFilter("QoSFilter", QoSFilter.class);
        
        qosFilter.setInitParameter(QoSFilter.MAX_REQUESTS_INIT_PARAM, "25");
        qosFilter.setInitParameter(QoSFilter.MAX_WAIT_INIT_PARAM, "75");
        qosFilter.setInitParameter(QoSFilter.SUSPEND_INIT_PARAM, "45000");
        qosFilter.setInitParameter(QoSFilter.MAX_PRIORITY_INIT_PARAM, "15");
        qosFilter.setInitParameter(QoSFilter.MANAGED_ATTR_INIT_PARAM, "true");
        
        qosFilter.addMappingForUrlPatterns(null, false, "/api/*", "/services/*");
    }
    
    public static void configureCustomPriorityFilter(ServletContext context) {
        FilterRegistration.Dynamic priorityFilter = context.addFilter("PriorityQoSFilter", 
                                                                      PriorityQoSFilter.class);
        
        priorityFilter.setInitParameter("maxRequests", "15");
        priorityFilter.setInitParameter("waitMs", "100");
        priorityFilter.setInitParameter("suspendMs", "30000");
        
        priorityFilter.addMappingForUrlPatterns(null, false, "/*");
    }
}

QoS Processing Flow

Request Processing Steps

  1. Request Arrival: Filter receives incoming request
  2. Priority Calculation: getPriority() method determines request priority
  3. Capacity Check: Filter checks if current requests < maxRequests
  4. Immediate Processing: If capacity available, request proceeds immediately
  5. Wait Period: If no capacity, request waits for waitMs milliseconds
  6. Suspension: After wait period, request is suspended for up to suspendMs
  7. Queue Management: Suspended requests are queued by priority
  8. Resume Processing: When capacity becomes available, highest priority request is resumed

Priority-Based Queuing

Requests are queued in priority order when server capacity is exceeded:

  • Higher priority numbers = higher precedence
  • Equal priority requests are processed in FIFO order
  • Priority range: 1 to maxPriority (default 1-10)

JMX Management

When managedAttr is enabled, the filter exposes JMX management capabilities:

// Access QoS metrics via ServletContext
QoSFilter qosFilter = (QoSFilter) servletContext.getAttribute("QoSFilter");

// Get current configuration
int maxRequests = qosFilter.getMaxRequests();
long waitTime = qosFilter.getWaitMs();
long suspendTime = qosFilter.getSuspendMs();

// Monitor current state (implementation-dependent)
// Actual metrics depend on JMX integration

Performance Considerations

Capacity Planning

  • Set maxRequests based on server resources and expected load
  • Consider memory usage: each suspended request consumes resources
  • Monitor queue lengths and suspension times

Wait vs Suspend Times

  • waitMs: Short wait before suspension (reduces unnecessary suspensions)
  • suspendMs: Maximum time a request can be suspended (prevents indefinite waits)
  • Balance between responsiveness and resource utilization

Priority Strategy

  • Use priorities sparingly - too many levels can complicate management
  • Base priorities on business logic rather than technical metrics
  • Consider the impact of priority inversions

Migration Guide

Since QoSFilter is deprecated, consider migrating to org.eclipse.jetty.server.handler.QoSHandler:

// Old approach (deprecated)
QoSFilter filter = new QoSFilter();

// New approach (recommended)  
QoSHandler handler = new QoSHandler();
handler.setMaxRequestCount(25);
handler.setMaxSuspendTime(30000);

The new handler provides:

  • Better integration with Jetty's async processing
  • Improved performance and resource management
  • More flexible configuration options
  • Better monitoring and management capabilities

Common Use Cases

API Rate Limiting

Prevent API overload by limiting concurrent requests per endpoint.

Resource Protection

Protect database connections and expensive operations from overwhelming traffic.

User Experience

Maintain responsive user interfaces by prioritizing interactive requests over batch operations.

System Stability

Prevent server crashes due to resource exhaustion during traffic spikes.

Install with Tessl CLI

npx tessl i tessl/maven-org-eclipse-jetty-ee10--jetty-ee10-servlets

docs

base-filtering.md

cors-filter.md

dos-protection.md

header-management.md

index.md

quality-of-service.md

server-sent-events.md

tile.json