diff options
author | Michael Gorovoy | 2010-06-02 02:29:05 +0000 |
---|---|---|
committer | Michael Gorovoy | 2010-06-02 02:29:05 +0000 |
commit | 716b76fe5d150f1344a98730d45e819baaebc35b (patch) | |
tree | f0966f51aa06f685f1b433ee82f4a9ab906f08b1 | |
parent | 727e58b0b4efb3bad2b438801e2d275b1c928693 (diff) | |
download | org.eclipse.jetty.project-716b76fe5d150f1344a98730d45e819baaebc35b.tar.gz org.eclipse.jetty.project-716b76fe5d150f1344a98730d45e819baaebc35b.tar.xz org.eclipse.jetty.project-716b76fe5d150f1344a98730d45e819baaebc35b.zip |
292814 make QoSFilter and DoSFilter JMX manageable
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@1913 7e9141cc-0065-0410-87d8-b60c137991c4
-rw-r--r-- | jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java | 304 | ||||
-rw-r--r-- | jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java | 93 |
2 files changed, 376 insertions, 21 deletions
diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java index f2355f4014..02636623da 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/DoSFilter.java @@ -125,18 +125,20 @@ public class DoSFilter implements Filter protected long _delayMs; protected long _throttleMs; - protected long _waitMs; + protected long _maxWaitMs; protected long _maxRequestMs; protected long _maxIdleTrackerMs; protected boolean _insertHeaders; protected boolean _trackSessions; protected boolean _remotePort; + protected int _throttledRequests; protected Semaphore _passes; protected Queue<Continuation>[] _queue; protected ContinuationListener[] _listener; protected int _maxRequestsPerSec; protected final ConcurrentHashMap<String, RateTracker> _rateTrackers=new ConcurrentHashMap<String, RateTracker>(); + protected String _whitelistStr; private final HashSet<String> _whitelist = new HashSet<String>(); private final Timeout _requestTimeoutQ = new Timeout(); @@ -170,7 +172,6 @@ public class DoSFilter implements Filter } _rateTrackers.clear(); - _whitelist.clear(); int baseRateLimit = __DEFAULT_MAX_REQUESTS_PER_SEC; if (filterConfig.getInitParameter(MAX_REQUESTS_PER_S_INIT_PARAM) != null) @@ -182,15 +183,15 @@ public class DoSFilter implements Filter delay = Integer.parseInt(filterConfig.getInitParameter(DELAY_MS_INIT_PARAM)); _delayMs = delay; - int passes = __DEFAULT_THROTTLE; + _throttledRequests = __DEFAULT_THROTTLE; if (filterConfig.getInitParameter(THROTTLED_REQUESTS_INIT_PARAM) != null) - passes = Integer.parseInt(filterConfig.getInitParameter(THROTTLED_REQUESTS_INIT_PARAM)); - _passes = new Semaphore(passes,true); + _throttledRequests = Integer.parseInt(filterConfig.getInitParameter(THROTTLED_REQUESTS_INIT_PARAM)); + _passes = new Semaphore(_throttledRequests,true); long wait = __DEFAULT_WAIT_MS; if (filterConfig.getInitParameter(MAX_WAIT_INIT_PARAM) != null) wait = Integer.parseInt(filterConfig.getInitParameter(MAX_WAIT_INIT_PARAM)); - _waitMs = wait; + _maxWaitMs = wait; long suspend = __DEFAULT_THROTTLE_MS; if (filterConfig.getInitParameter(THROTTLE_MS_INIT_PARAM) != null) @@ -207,18 +208,10 @@ public class DoSFilter implements Filter maxIdleTrackerMs = Long.parseLong(filterConfig.getInitParameter(MAX_IDLE_TRACKER_MS_INIT_PARAM)); _maxIdleTrackerMs = maxIdleTrackerMs; - String whitelistString = ""; + _whitelistStr = ""; if (filterConfig.getInitParameter(IP_WHITELIST_INIT_PARAM) !=null ) - whitelistString = filterConfig.getInitParameter(IP_WHITELIST_INIT_PARAM); - - if (whitelistString.length() > 0) - { - StringTokenizer tokenizer = new StringTokenizer(whitelistString, ","); - while (tokenizer.hasMoreTokens()) - _whitelist.add(tokenizer.nextToken().trim()); - - Log.info("Whitelisted IP addresses: {}", _whitelist.toString()); - } + _whitelistStr = filterConfig.getInitParameter(IP_WHITELIST_INIT_PARAM); + initWhitelist(); String tmp = filterConfig.getInitParameter(INSERT_HEADERS_INIT_PARAM); _insertHeaders = tmp==null || Boolean.parseBoolean(tmp); @@ -342,7 +335,7 @@ public class DoSFilter implements Filter try { // check if we can afford to accept another request at this time - accepted = _passes.tryAcquire(_waitMs,TimeUnit.MILLISECONDS); + accepted = _passes.tryAcquire(_maxWaitMs,TimeUnit.MILLISECONDS); if (!accepted) { @@ -607,6 +600,281 @@ public class DoSFilter implements Filter return null; } + /* ------------------------------------------------------------ */ + /** + * Initialize the IP address whitelist + */ + protected void initWhitelist() + { + _whitelist.clear(); + StringTokenizer tokenizer = new StringTokenizer(_whitelistStr, ","); + while (tokenizer.hasMoreTokens()) + _whitelist.add(tokenizer.nextToken().trim()); + + Log.info("Whitelisted IP addresses: {}", _whitelist.toString()); + } + + /* ------------------------------------------------------------ */ + /** + * Get maximum number of requests from a connection per + * second. Requests in excess of this are first delayed, + * then throttled. + * + * @return maximum number of requests + */ + public int getMaxRequestsPerSec() + { + return _maxRequestsPerSec; + } + + /* ------------------------------------------------------------ */ + /** + * Get maximum number of requests from a connection per + * second. Requests in excess of this are first delayed, + * then throttled. + * + * @param value maximum number of requests + */ + public void setMaxRequestsPerSec(int value) + { + _maxRequestsPerSec = value; + } + + /* ------------------------------------------------------------ */ + /** + * Get delay (in milliseconds) that is applied to all requests + * over the rate limit, before they are considered at all. + */ + public long getDelayMs() + { + return _delayMs; + } + + /* ------------------------------------------------------------ */ + /** + * Set delay (in milliseconds) that is applied to all requests + * over the rate limit, before they are considered at all. + * + * @param value delay (in milliseconds), 0 - no delay, -1 - reject request + */ + public void setDelayMs(long value) + { + _delayMs = value; + } + + /* ------------------------------------------------------------ */ + /** + * Get maximum amount of time (in milliseconds) the filter will + * blocking wait for the throttle semaphore. + * + * @return maximum wait time + */ + public long getMaxWaitMs() + { + return _maxWaitMs; + } + + /* ------------------------------------------------------------ */ + /** + * Set maximum amount of time (in milliseconds) the filter will + * blocking wait for the throttle semaphore. + * + * @param value maximum wait time + */ + public void setMaxWaitMs(long value) + { + _maxWaitMs = value; + } + + /* ------------------------------------------------------------ */ + /** + * Get number of requests over the rate limit able to be + * considered at once. + * + * @return number of requests + */ + public long getThrottledRequests() + { + return _throttledRequests; + } + + /* ------------------------------------------------------------ */ + /** + * Set number of requests over the rate limit able to be + * considered at once. + * + * @param value number of requests + */ + public void setThrottledRequests(int value) + { + _passes = new Semaphore((value-_throttledRequests+_passes.availablePermits()), true); + _throttledRequests = value; + } + + /* ------------------------------------------------------------ */ + /** + * Get amount of time (in milliseconds) to async wait for semaphore. + * + * @return wait time + */ + public long getThrottleMs() + { + return _throttleMs; + } + + /* ------------------------------------------------------------ */ + /** + * Set amount of time (in milliseconds) to async wait for semaphore. + * + * @param value wait time + */ + public void setThrottleMs(long value) + { + _throttleMs = value; + } + + /* ------------------------------------------------------------ */ + /** + * Get maximum amount of time (in milliseconds) to allow + * the request to process. + * + * @return maximum processing time + */ + public long getMaxRequestMs() + { + return _maxRequestMs; + } + + /* ------------------------------------------------------------ */ + /** + * Set maximum amount of time (in milliseconds) to allow + * the request to process. + * + * @param value maximum processing time + */ + public void setMaxRequestMs(long value) + { + _maxRequestMs = value; + } + + /* ------------------------------------------------------------ */ + /** + * Get maximum amount of time (in milliseconds) to keep track + * of request rates for a connection, before deciding that + * the user has gone away, and discarding it. + * + * @return maximum tracking time + */ + public long getMaxIdleTrackerMs() + { + return _maxIdleTrackerMs; + } + + /* ------------------------------------------------------------ */ + /** + * Set maximum amount of time (in milliseconds) to keep track + * of request rates for a connection, before deciding that + * the user has gone away, and discarding it. + * + * @param value maximum tracking time + */ + public void setMaxIdleTrackerMs(long value) + { + _maxIdleTrackerMs = value; + } + + /* ------------------------------------------------------------ */ + /** + * Check flag to insert the DoSFilter headers into the response. + * + * @return value of the flag + */ + public boolean isInsertHeaders() + { + return _insertHeaders; + } + + /* ------------------------------------------------------------ */ + /** + * Set flag to insert the DoSFilter headers into the response. + * + * @param value value of the flag + */ + public void setInsertHeaders(boolean value) + { + _insertHeaders = value; + } + + /* ------------------------------------------------------------ */ + /** + * Get flag to have usage rate tracked by session if a session exists. + * + * @return value of the flag + */ + public boolean isTrackSessions() + { + return _trackSessions; + } + + /* ------------------------------------------------------------ */ + /** + * Set flag to have usage rate tracked by session if a session exists. + * @param value value of the flag + */ + public void setTrackSessions(boolean value) + { + _trackSessions = value; + } + + /* ------------------------------------------------------------ */ + /** + * Get flag to have usage rate tracked by IP+port (effectively connection) + * if session tracking is not used. + * + * @return value of the flag + */ + public boolean isRemotePort() + { + return _remotePort; + } + + + /* ------------------------------------------------------------ */ + /** + * Set flag to have usage rate tracked by IP+port (effectively connection) + * if session tracking is not used. + * + * @param value value of the flag + */ + public void setRemotePort(boolean value) + { + _remotePort = value; + } + + /* ------------------------------------------------------------ */ + /** + * Get a list of IP addresses that will not be rate limited. + * + * @return comma-separated whitelist + */ + public String getWhitelist() + { + return _whitelistStr; + } + + + /* ------------------------------------------------------------ */ + /** + * Set a list of IP addresses that will not be rate limited. + * + * @param value comma-separated whitelist + */ + public void setWhitelist(String value) + { + _whitelistStr = value; + initWhitelist(); + } + /** * A RateTracker is associated with a connection, and stores request rate * data. diff --git a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java index 21b6843c2c..bac4240f05 100644 --- a/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java +++ b/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java @@ -36,6 +36,7 @@ import org.eclipse.jetty.continuation.ContinuationSupport; /** * Quality of Service Filter. + * * This filter limits the number of active requests to the number set by the "maxRequests" init parameter (default 10). * If more requests are received, they are suspended and placed on priority queues. Priorities are determined by * the {@link #getPriority(ServletRequest)} method and are a value between 0 and the value given by the "maxPriority" @@ -79,11 +80,16 @@ public class QoSFilter implements Filter ServletContext _context; long _waitMs; long _suspendMs; + int _maxRequests; Semaphore _passes; Queue<Continuation>[] _queue; ContinuationListener[] _listener; String _suspended="QoSFilter@"+this.hashCode(); + /* ------------------------------------------------------------ */ + /** + * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) + */ public void init(FilterConfig filterConfig) { _context=filterConfig.getServletContext(); @@ -110,10 +116,10 @@ public class QoSFilter implements Filter }; } - int passes=__DEFAULT_PASSES; + int _maxRequests=__DEFAULT_PASSES; if (filterConfig.getInitParameter(MAX_REQUESTS_INIT_PARAM)!=null) - passes=Integer.parseInt(filterConfig.getInitParameter(MAX_REQUESTS_INIT_PARAM)); - _passes=new Semaphore(passes,true); + _maxRequests=Integer.parseInt(filterConfig.getInitParameter(MAX_REQUESTS_INIT_PARAM)); + _passes=new Semaphore(_maxRequests,true); long wait = __DEFAULT_WAIT_MS; if (filterConfig.getInitParameter(MAX_WAIT_INIT_PARAM)!=null) @@ -126,6 +132,10 @@ public class QoSFilter implements Filter _suspendMs=suspend; } + /* ------------------------------------------------------------ */ + /** + * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) + */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { @@ -238,6 +248,83 @@ public class QoSFilter implements Filter } + /* ------------------------------------------------------------ */ + /** + * @see javax.servlet.Filter#destroy() + */ public void destroy(){} + /* ------------------------------------------------------------ */ + /** + * Get the (short) amount of time (in milliseconds) that the filter would wait + * for the semaphore to become available before suspending a request. + * + * @return wait time (in milliseconds) + */ + public long getWaitMs() + { + return _waitMs; + } + + /* ------------------------------------------------------------ */ + /** + * Set the (short) amount of time (in milliseconds) that the filter would wait + * for the semaphore to become available before suspending a request. + * + * @param value wait time (in milliseconds) + */ + public void setWaitMs(long value) + { + _waitMs = value; + } + + /* ------------------------------------------------------------ */ + /** + * Get the amount of time (in milliseconds) that the filter would suspend + * a request for while waiting for the semaphore to become available. + * + * @return suspend time (in milliseconds) + */ + public long getSuspendMs() + { + return _suspendMs; + } + + /* ------------------------------------------------------------ */ + /** + * Set the amount of time (in milliseconds) that the filter would suspend + * a request for while waiting for the semaphore to become available. + * + * @param value suspend time (in milliseconds) + */ + public void setSuspendMs(long value) + { + _suspendMs = value; + } + + /* ------------------------------------------------------------ */ + /** + * Get the maximum number of requests allowed to be processed + * at the same time. + * + * @return maximum number of requests + */ + public int getMaxRequests() + { + return _maxRequests; + } + + /* ------------------------------------------------------------ */ + /** + * Set the maximum number of requests allowed to be processed + * at the same time. + * + * @param passes the _passes to set + */ + public void setMaxRequests(int value) + { + _passes = new Semaphore((value-_maxRequests+_passes.availablePermits()), true); + _maxRequests = value; + } + } |