baiheqiang / memcached-session-manager

Automatically exported from code.google.com/p/memcached-session-manager
0 stars 0 forks source link

Secondary session backup is tried to be removed with non-sticky sessions and only a single memcached #95

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
When msm is configured with non-sticky sessions and there's only a single 
memcached node it tries to delete the secondary session backup on session 
expiration. This fails as there's no secondary session backup.

This was originally reported by email:

Hello Martin,

I email you directly cos I do not know how to open a bug against your project. 
This weekend I have been testing some tomcat HA solutions and I was very 
interested in setting up a membase solution with your 
memcached-session-manager. The problem I saw is that when only one memcached is 
configured (no backup) a lot of objects are not correctly removed form 
memcached, the following exception was always thrown:

Mar 26, 2011 1:33:01 PM de.javakaffee.web.msm.MemcachedBackupSessionManager 
deleteFromMemcached
INFO: Could not delete session from memcached.
java.lang.IllegalArgumentException: No node found for key 
bak:C74B563CF0ABF88CC88079FE3F80F377-n1.debian2
       at de.javakaffee.web.msm.SuffixBasedNodeLocator.getPrimary(SuffixBasedNodeLocator.java:93)
       at net.spy.memcached.MemcachedConnection.addOperation(MemcachedConnection.java:558)
       at net.spy.memcached.MemcachedClient.addOp(MemcachedClient.java:277)
       at net.spy.memcached.MemcachedClient.delete(MemcachedClient.java:1476)
       at de.javakaffee.web.msm.LockingStrategy.onAfterDeleteFromMemcached(LockingStrategy.java:360)
       at de.javakaffee.web.msm.MemcachedBackupSessionManager.deleteFromMemcached(MemcachedBackupSessionManager.java:668)
       at de.javakaffee.web.msm.MemcachedBackupSessionManager.remove(MemcachedBackupSessionManager.java:982)
       at de.javakaffee.web.msm.MemcachedBackupSessionManager.remove(MemcachedBackupSessionManager.java:973)
       at org.apache.catalina.session.StandardSession.expire(StandardSession.java:766)
       at org.apache.catalina.session.StandardSession.expire(StandardSession.java:643)
       at org.apache.catalina.session.StandardSession.invalidate(StandardSession.java:1148)
       at org.apache.catalina.session.StandardSessionFacade.invalidate(StandardSessionFacade.java:150)
       at org.apache.jsp.ClearSession_jsp._jspService(ClearSession_jsp.java:62)
       at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
       at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:377)
       at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
       at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
       at de.javakaffee.web.msm.SessionTrackerValve.invoke(SessionTrackerValve.java:146)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
       at org.apache.jk.server.JkCoyoteHandler.invoke(JkCoyoteHandler.java:190)
       at org.apache.jk.common.HandlerRequest.invoke(HandlerRequest.java:291)
       at org.apache.jk.common.ChannelSocket.invoke(ChannelSocket.java:774)
       at org.apache.jk.common.ChannelSocket.processConnection(ChannelSocket.java:703)
       at org.apache.jk.common.ChannelSocket$SocketConnection.runIt(ChannelSocket.java:896)
       at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:690)
       at java.lang.Thread.run(Thread.java:636)

If you see the LockingStrategy.java, the problem is  you always remove the 
backup key in onAfterDeleteFromMemcached (but I have only one memcached server) 
so the previous exception is thrown and the next deletion (validityInfoKey) is 
not done. I fixed this issue with this simple patch:

--- LockingStrategy.java    2011-03-03 09:02:44.000000000 +0100
+++ LockingStrategy.java.RICKY    2011-03-26 23:31:06.246888265 +0100
@@ -357,10 +357,13 @@
    protected void onAfterDeleteFromMemcached( @Nonnull final String sessionId ) {
        final long start = System.currentTimeMillis();

+    if (_storeSecondaryBackup)
        _memcached.delete( _sessionIdFormat.createBackupKey( sessionId ) );

        final String validityInfoKey = createValidityInfoKeyName( sessionId );
        _memcached.delete( validityInfoKey );
+
+    if (_storeSecondaryBackup)
        _memcached.delete( _sessionIdFormat.createBackupKey( validityInfoKey ) );

        _stats.registerSince( NON_STICKY_AFTER_DELETE_FROM_MEMCACHED, start );

As you see I only check if _storeSecondaryBackup is true to not try to delete 
if no backup memcached is configured.

Original issue reported on code.google.com by martin.grotzke on 28 Mar 2011 at 10:04

GoogleCodeExporter commented 8 years ago
Fixed in master and tomcat7 branch.

Original comment by martin.grotzke on 28 Mar 2011 at 10:08