Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Gorovoy2010-06-02 02:29:05 +0000
committerMichael Gorovoy2010-06-02 02:29:05 +0000
commit716b76fe5d150f1344a98730d45e819baaebc35b (patch)
treef0966f51aa06f685f1b433ee82f4a9ab906f08b1
parent727e58b0b4efb3bad2b438801e2d275b1c928693 (diff)
downloadorg.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.java304
-rw-r--r--jetty-servlets/src/main/java/org/eclipse/jetty/servlets/QoSFilter.java93
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;
+ }
+
}

Back to the top