Class RequestThrottler

  • All Implemented Interfaces:
    javax.servlet.Filter

    public class RequestThrottler
    extends Object
    implements javax.servlet.Filter
    Allows to throttle certain requests, that means limit the amount of requests matching some path criteria per minute. The primary goal of this implementation is to prevent that some requests are eating up all available CPUs, while others (more important) requests will be impacted by this behavior. This implementation should be activating itself by detecting such situations and start throttling requests. A simple usecase for this can be to limit the number if incoming replication requests and allow more "other" requests be handled. Requests which are supposed to handled by this implementation must match one of the configured regular expressions in
     filtered_paths
     
    . Other requests are not considered at all by the throttling implementation. The throttling algorithm is loosely based on the leaky bucket approach, but it allows to adjust the throttling based on CPU load. This means:
    • If the CPU usage is smaller than
       start_throttling_percentage
       
      , than no throttling is active at all. If you set this value to "0", throttling will always be active.
    • If the CPU usage is higher than the configured
       start_throttling_percentage
       
      , the throttling algorithm is used. It permits at maximum
       max_requests_per_minute
       
      requests per minute to pass, all other requests will be throttled.
    The number of requests which are permitted to pass the throttling approach, is determined solely by CPU load; this number starts at the configured maximum (
     max_requests_per_minute
     
    and decreases linearly as the CPU usages increases. At 100% usage the number of permitted requests is 0 (zero) and all requests (matching the expression in
     filtered_paths
     
    are throttled. This implementation supports 2 modes of throttling:
    • rejecting the request with a configurable HTTP statuscode; is should be used in cases when the client is able to handle this case.
    • Or blocking the request unless it can be handled. This is transparent for the client (the request might time out, though!), but it blocks this requests for the complete time, which might lead to a shortage of threads.
    • Constructor Detail

      • RequestThrottler

        public RequestThrottler()
    • Method Detail

      • doFilter

        public void doFilter​(javax.servlet.ServletRequest request,
                             javax.servlet.ServletResponse response,
                             javax.servlet.FilterChain chain)
                      throws IOException,
                             javax.servlet.ServletException
        Specified by:
        doFilter in interface javax.servlet.Filter
        Throws:
        IOException
        javax.servlet.ServletException
      • doFilterInternal

        protected void doFilterInternal​(org.apache.sling.api.SlingHttpServletRequest req,
                                        org.apache.sling.api.SlingHttpServletResponse res)
                                 throws IOException
        Throws:
        IOException
      • needsFiltering

        protected boolean needsFiltering​(String path)
      • delay

        protected void delay​(long ms)
      • init

        public void init​(javax.servlet.FilterConfig arg0)
                  throws javax.servlet.ServletException
        Specified by:
        init in interface javax.servlet.Filter
        Throws:
        javax.servlet.ServletException
      • destroy

        public void destroy()
        Specified by:
        destroy in interface javax.servlet.Filter