Author: markt
Date: Thu Jan 20 18:10:16 2011
New Revision: 1061433
URL: http://svn.apache.org/viewvc?rev=1061433&view=rev
Log:
Add session creation / expiration rate statistics to the session managers
Adds ~10% to the session creation/destruction process when that is all Tomcat
is doing. Should be less overhead with less contention.
Modified:
tomcat/tc6.0.x/trunk/STATUS.txt
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/session/DeltaManager.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/ManagerBase.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/StandardSession.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/mbeans-descriptors.xml
tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
Modified: tomcat/tc6.0.x/trunk/STATUS.txt
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=1061433&r1=1061432&r2=1061433&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/STATUS.txt (original)
+++ tomcat/tc6.0.x/trunk/STATUS.txt Thu Jan 20 18:10:16 2011
@@ -89,16 +89,6 @@ PATCHES PROPOSED TO BACKPORT:
We can stall this item until we get some feedback about 7.0.5.
-1:
-* Add session creation / expiration rate statistics to the session managers
- Adds ~10% to the session creation/destruction process when that is all Tomcat
- is doing. Should be less overhead with less contention.
- http://people.apache.org/~markt/patches/2010-11-18-session-rate-stats.patch
- +1: markt, rjung, fhanik
- -1:
- rjung: getSessionExpireRate() and getSessionCreateRate() could share a common
- implementation (same method body except for the input list). The
member
- "duration" of SessionTiming does not seem to get used.
-
* Backport AprEndpoint shutdown patch (BZ49795 and similar).
http://people.apache.org/~mturk/tomcat/patches/tomcat-6.0.x-aprshutdown.patch
+1: mturk
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/session/DeltaManager.java
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/session/DeltaManager.java?rev=1061433&r1=1061432&r2=1061433&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/session/DeltaManager.java
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/ha/session/DeltaManager.java
Thu Jan 20 18:10:16 2011
@@ -40,6 +40,7 @@ import org.apache.catalina.core.Standard
import org.apache.catalina.ha.CatalinaCluster;
import org.apache.catalina.ha.ClusterMessage;
import org.apache.catalina.ha.tcp.ReplicationValve;
+import org.apache.catalina.session.ManagerBase;
import org.apache.catalina.tribes.Member;
import org.apache.catalina.tribes.io.ReplicationStream;
import org.apache.catalina.util.LifecycleSupport;
@@ -1286,6 +1287,16 @@ public class DeltaManager extends Cluste
public synchronized void resetStatistics() {
processingTime = 0 ;
expiredSessions = 0 ;
+ sessionCreationTiming.clear();
+ while (sessionCreationTiming.size() <
+ ManagerBase.TIMING_STATS_CACHE_SIZE) {
+ sessionCreationTiming.add(null);
+ }
+ sessionExpirationTiming.clear();
+ while (sessionExpirationTiming.size() <
+ ManagerBase.TIMING_STATS_CACHE_SIZE) {
+ sessionExpirationTiming.add(null);
+ }
rejectedSessions = 0 ;
sessionReplaceCounter = 0 ;
counterNoStateTransfered = 0 ;
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/ManagerBase.java
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/ManagerBase.java?rev=1061433&r1=1061432&r2=1061433&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/ManagerBase.java
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/ManagerBase.java Thu
Jan 20 18:10:16 2011
@@ -30,10 +30,13 @@ import java.security.AccessController;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedAction;
+import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
@@ -165,6 +168,15 @@ public abstract class ManagerBase implem
protected int sessionAverageAliveTime;
+ protected static final int TIMING_STATS_CACHE_SIZE = 100;
+
+ protected LinkedList<SessionTiming> sessionCreationTiming =
+ new LinkedList<SessionTiming>();
+
+ protected LinkedList<SessionTiming> sessionExpirationTiming =
+ new LinkedList<SessionTiming>();
+
+
/**
* Number of sessions that have expired.
*/
@@ -752,6 +764,15 @@ public abstract class ManagerBase implem
// Initialize random number generation
getRandomBytes(new byte[16]);
+ // Ensure caches for timing stats are the right size by filling with
+ // nulls.
+ while (sessionCreationTiming.size() < TIMING_STATS_CACHE_SIZE) {
+ sessionCreationTiming.add(null);
+ }
+ while (sessionExpirationTiming.size() < TIMING_STATS_CACHE_SIZE) {
+ sessionExpirationTiming.add(null);
+ }
+
if(log.isDebugEnabled())
log.debug("Registering " + oname );
@@ -860,6 +881,11 @@ public abstract class ManagerBase implem
session.setId(sessionId);
sessionCounter++;
+ SessionTiming timing = new SessionTiming(session.getCreationTime(), 0);
+ synchronized (sessionCreationTiming) {
+ sessionCreationTiming.add(timing);
+ sessionCreationTiming.poll();
+ }
return (session);
}
@@ -1167,6 +1193,91 @@ public abstract class ManagerBase implem
}
+ /**
+ * Gets the current rate of session creation (in session per minute) based
+ * on the creation time of the previous 100 sessions created. If less than
+ * 100 sessions have been created then all available data is used.
+ *
+ * @return The current rate (in sessions per minute) of session creation
+ */
+ public int getSessionCreateRate() {
+ long now = System.currentTimeMillis();
+ // Copy current stats
+ List<SessionTiming> copy = new ArrayList<SessionTiming>();
+ synchronized (sessionCreationTiming) {
+ copy.addAll(sessionCreationTiming);
+ }
+
+ // Init
+ long oldest = now;
+ int counter = 0;
+ int result = 0;
+ Iterator<SessionTiming> iter = copy.iterator();
+
+ // Calculate rate
+ while (iter.hasNext()) {
+ SessionTiming timing = iter.next();
+ if (timing != null) {
+ counter++;
+ if (timing.getTimestamp() < oldest) {
+ oldest = timing.getTimestamp();
+ }
+ }
+ }
+ if (counter > 0) {
+ if (oldest < now) {
+ result = (int) ((1000*60*counter)/(now - oldest));
+ } else {
+ result = Integer.MAX_VALUE;
+ }
+ }
+ return result;
+ }
+
+
+ /**
+ * Gets the current rate of session expiration (in session per minute)
based
+ * on the expiry time of the previous 100 sessions expired. If less than
+ * 100 sessions have expired then all available data is used.
+ *
+ * @return The current rate (in sessions per minute) of session expiration
+ */
+ public int getSessionExpireRate() {
+ long now = System.currentTimeMillis();
+ // Copy current stats
+ List<SessionTiming> copy = new ArrayList<SessionTiming>();
+ synchronized (sessionExpirationTiming) {
+ copy.addAll(sessionExpirationTiming);
+ }
+
+ // Init
+ long oldest = now;
+ int counter = 0;
+ int result = 0;
+ Iterator<SessionTiming> iter = copy.iterator();
+
+ // Calculate rate
+ while (iter.hasNext()) {
+ SessionTiming timing = iter.next();
+ if (timing != null) {
+ counter++;
+ if (timing.getTimestamp() < oldest) {
+ oldest = timing.getTimestamp();
+ }
+ }
+ }
+ if (counter > 0) {
+ if (oldest < now) {
+ result = (int) ((1000*60*counter)/(now - oldest));
+ } else {
+ // Better than reporting zero
+ result = Integer.MAX_VALUE;
+ }
+ }
+ return result;
+ }
+
+
/**
* For debugging: return a list of all session ids currently active
*
@@ -1311,4 +1422,30 @@ public abstract class ManagerBase implem
public void postDeregister() {
}
+ // ----------------------------------------------------------- Inner
classes
+
+ protected static final class SessionTiming {
+ private long timestamp;
+ private int duration;
+
+ public SessionTiming(long timestamp, int duration) {
+ this.timestamp = timestamp;
+ this.duration = duration;
+ }
+
+ /**
+ * Time stamp associated with this piece of timing information in
+ * milliseconds.
+ */
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ /**
+ * Duration associated with this piece of timing information in
seconds.
+ */
+ public int getDuration() {
+ return duration;
+ }
+ }
}
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/StandardSession.java
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/StandardSession.java?rev=1061433&r1=1061432&r2=1061433&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/StandardSession.java
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/StandardSession.java
Thu Jan 20 18:10:16 2011
@@ -59,6 +59,7 @@ import org.apache.catalina.util.StringMa
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.realm.GenericPrincipal;
import org.apache.catalina.security.SecurityUtil;
+import org.apache.catalina.session.ManagerBase.SessionTiming;
/**
* Standard implementation of the <b>Session</b> interface. This object is
@@ -762,6 +763,15 @@ public class StandardSession
manager.setSessionAverageAliveTime(average);
}
+ if (manager instanceof ManagerBase) {
+ ManagerBase mb = (ManagerBase) manager;
+ SessionTiming timing = new SessionTiming(timeNow, timeAlive);
+ synchronized (mb.sessionExpirationTiming) {
+ mb.sessionExpirationTiming.add(timing);
+ mb.sessionExpirationTiming.poll();
+ }
+ }
+
// Remove this session from our manager's active sessions
manager.remove(this);
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/mbeans-descriptors.xml
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/mbeans-descriptors.xml?rev=1061433&r1=1061432&r2=1061433&view=diff
==============================================================================
---
tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/mbeans-descriptors.xml
(original)
+++
tomcat/tc6.0.x/trunk/java/org/apache/catalina/session/mbeans-descriptors.xml
Thu Jan 20 18:10:16 2011
@@ -83,10 +83,20 @@
type="int"
writeable="false"/>
+ <attribute name="sessionCreateRate"
+ description="Session creation rate in sessions per minute"
+ type="int"
+ writeable="false" />
+
<attribute name="sessionCounter"
description="Total number of sessions created by this manager"
type="int" />
-
+
+ <attribute name="sessionExpireRate"
+ description="Session expiration rate in sessions per minute"
+ type="int"
+ writeable="false" />
+
<attribute name="maxActive"
description="Maximum number of active sessions so far"
type="int" />
@@ -245,10 +255,20 @@
type="int"
writeable="false"/>
+ <attribute name="sessionCreateRate"
+ description="Session creation rate in sessions per minute"
+ type="int"
+ writeable="false" />
+
<attribute name="sessionCounter"
description="Total number of sessions created by this manager"
type="int" />
-
+
+ <attribute name="sessionExpireRate"
+ description="Session expiration rate in sessions per minute"
+ type="int"
+ writeable="false" />
+
<attribute name="maxActive"
description="Maximum number of active sessions so far"
type="int" />
Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=1061433&r1=1061432&r2=1061433&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Thu Jan 20 18:10:16 2011
@@ -59,6 +59,10 @@
ensure that a subsequent request for that directory does not result in
a
404 response. (markt/kkolinko)
</fix>
+ <add>
+ Provide session creation and destruction rate metrics in the session
+ managers. (markt)
+ </add>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]