|
SetupAndConfiguration
This page shows what's necessary to get the memcached-session-manager up and running.
Featured, Phase-Deploy
IntroductionFor the most simple integration you just need to have a tomcat (6 or 7) and a memcached installed (or s.th. supporting the memcached protocol). In your production environment you probably will have several tomcats and you should also have several memcached nodes available, on different pieces of hardware. You can use sticky sessions or non-sticky sessions, memcached-session-manager (msm) supports both operation modes. The following description shows an example for a setup with sticky sessions, with two instances of tomcat and two instances of memcached installed. Tomcat-1 (t1) will primarily store it's sessions in memcached-2 (m2) which is running on another machine (m2 is a regular node for t1). Only if m2 is not available, t1 will store it's sessions in memcached-1 (m1, m1 is the failoverNode for t1). With this configuration, sessions won't be lost when machine 1 (serving t1 and m1) crashes. The following really nice ASCII art shows this setup. <t1> <t2> . \ / . . X . . / \ . <m1> <m2> So what needs to be done for this? Decide which serialization strategy to useStarting with release 1.1 there are several session serialization strategies available, as they are described on SerializationStrategies. The default strategy uses java serialization and is already provided by the memcached-session-manager jar. Other strategies are provided by separate jars, in the section below you'll see which jars are required for which strategy. Configure tomcatThe configuration of tomcat requires two things: you need to drop some jars in your $CATALINA_HOME/lib/ and WEB-INF/lib/ directories and you have to configure the memcached session manager in the related <Context> element (e.g. in $CATALINA_HOME/conf/context.xml). Add memcached-session-manager jars to tomcatIndependent of the chosen serialization strategy you always need the memcached-session-manager-${version}.jar and either memcached-session-manager-tc6-${version}.jar for tomcat6 or memcached-session-manager-tc7-${version}.jar for tomcat7. Also the spymemcached-2.7.3.jar. Just download and put them in $CATALINA_HOME/lib/. Add custom serializers to your webapp (optional)If you want to use java's built in serialization nothing more has to be done. If you want to use a custom serialization strategy (e.g. because of better performance) this has to be deployed with your webapp so that they're available in WEB-INF/lib/. As msm is available in maven central (under groupId de.javakaffee.msm) you can just pull it in using the dependency management of your build system. With maven you can use this dependency definition for the kryo-serializer: <dependency>
<groupId>de.javakaffee.msm</groupId>
<artifactId>msm-kryo-serializer</artifactId>
<version>1.6.0</version>
<scope>runtime</scope>
</dependency>For javolution the artifactId is msm-javolution-serializer, for xstream msm-xstream-serializer and for flexjson it's msm-flexjson-serializer. If you're not using a dependency management based on maven repositories these are the jars you need for the different serializers:
Configure memcached-session-manager as <Context> ManagerUpdate the <Context> element (in $CATALINA_HOME/conf/context.xml or what else you choose for context definition, please check the related tomcat documentation for this) so that it contains the Manager configuration for the memcached-session-manager, like in the examples below. The following examples show configurations for sticky sessions and non-sticky sessions with memcached servers and for non-sticky sessions with membase. The examples with memcached servers assume that there are two memcacheds running, one on host1 and another one on host2. All sample configurations assume that you want to use kryo based serialization. The following example shows the configuration of the first tomcat, assuming that it runs on host1, together with memcached "n1". The attribute failoverNodes="n1" tells msm to store sessions preferably in memcached "n2" and only store sessions in "n1" (running on the same host/machine) if no other memcached node (here only n2) is available (even if host1 goes down completely, the session is still available in memcached "n2" and could be served by the tomcat on host2). For the second tomcat (on host2) you just need to change the failover node to "n2", so that it prefers the memcached "n1". Everything else should be left unchanged. <Context>
...
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:host1.yourdomain.com:11211,n2:host2.yourdomain.com:11211"
failoverNodes="n1"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
</Context>The following example shows a configuration for non-sticky sessions. In this case there's no need for failoverNodes, as sessions are served by all tomcats round-robin and they're not bound to a single tomcat. For non-sticky sessions the configuration (for both/all tomcats) would look like this: <Context>
...
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:host1.yourdomain.com:11211,n2:host2.yourdomain.com:11211"
sticky="false"
sessionBackupAsync="false"
lockingMode="uriPattern:/path1|/path2"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
</Context>To connect to a membase bucket "bucket1" the configuration would look like this: <Context>
...
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="http://host1.yourdomain.com:8091/pools"
username="bucket1"
password="topsecret"
memcachedProtocol="binary"
sticky="false"
sessionBackupAsync="false"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
/>
</Context>More details for all configuration attributes are provided in the section below. After you have configured msm in the Context/Manager element, you can just start your application and sessions will be stored in the memcached nodes or in membase as configured. Now you should do some tests with a simulated tomcat failure, a restart of a memcached node etc. - have fun! :-) Overview over memcached-session-manager configuration attributesclassName (required) This should be set to de.javakaffee.web.msm.MemcachedBackupSessionManager to get sessions stored in memcached. However, since version 1.3.6 there's also a de.javakaffee.web.msm.DummyMemcachedBackupSessionManager that can be used for development purposes: it simply serializes sessions to a special in memory map and deserializes the serialized data at the next request when a session is requested (without really using this session) - just to see if deserialization is working for each request. Your application is still using sessions as if the memcached-session-manager (or DummyMemcachedBackupSessionManager) would not be existing. Session serialization/deserialization is done asynchronously. The configuration attributes memcachedNodes and failoverNode are not used to create a memcached client, so serialized session data will not be sent to memcached - and therefore no running memcacheds are required. memcachedNodes (required) This attribute must contain all memcached nodes you have running, or the membase bucket uri(s). It should be the same for all tomcats. failoverNodes (optional, must not be used for non-sticky sessions) This attribute must contain the ids of the memcached nodes, that shall not be used by this tomcat for session backup, but only if no other memcached nodes are available. Therefore, you should list those memcached nodes, that are running on the same machine as this tomcat. Several memcached node ids are separated by space or comma. For non-sticky sessions failoverNodes must not be specified as a session is not tied to a single tomcat. For membase buckets this attribute should also be left out. username (since 1.6.0, optional) Specifies the username used for a membase bucket or SASL. If the memcachedNodes contains a membase bucket uri (or multiple) this is the bucket name. If the memcachedNodes contains memcached node definitions this is the username used for SASL authentication. Both require the binary memcached protocol. password (since 1.6.0, optional) Specifies the password used for membase bucket or SASL authentication (can be left empty / omitted if the "default" membase bucket without a password shall be used). memcachedProtocol (since 1.3, optional, default text) This attribute specifies the memcached protocol to use, one of text or binary. sticky (since 1.4.0, optional, default true) Specifies if sticky or non-sticky sessions are used. lockingMode (since 1.4.0, optional, for non-sticky sessions only, default none) Specifies the locking strategy for non-sticky sessions. Session locking is useful to prevent concurrent modifications and lost updates of the session in the case of parallel requests (tabbed browsing with long requests, ajax etc.). Session locking is done using memcached. Possible values for lockingMode are: requestUriIgnorePattern (optional) This attribute contains a regular expression for request URIs, that shall not trigger a session backup. If static resources like css, javascript, images etc. are delivered by the same tomcat and the same web application context these requests will also pass the memcached-session-manager. However, as these requests should not change anything in a http session, they should also not trigger a session backup. So you should check if any static resources are delivered by tomcat and in this case you should exclude them by using this attribute. The requestUriIgnorePattern must follow the java regex Pattern. sessionBackupAsync (optional, default true) Specifies if the session shall be stored asynchronously in memcached. If this is true, the backupThreadCount setting is evaluated. If this is false, the timeout set via sessionBackupTimeout is evaluated. backupThreadCount (since 1.3, optional, default number-of-cpu-cores) The number of threads that are used for asynchronous session backup (if sessionBackupAsync="true"). For the default value the number of available processors (cores) is used. sessionBackupTimeout (optional, default 100) The timeout in milliseconds after that a session backup is considered as beeing failed. This property is only evaluated if sessions are stored synchronously (set via sessionBackupAsync). The default value is 100 milliseconds. operationTimeout (since 1.6.0, optional, default 1000) The memcached operation timeout used at various places, e.g. used for the spymemcached ConnectionFactory. sessionAttributeFilter (since 1.5.0, optional) A regular expression to control which session attributes are serialized to memcached. The regular expression is evaluated with session attribute names. E.g. sessionAttributeFilter="^(userName|sessionHistory)$" specifies that only "userName" and "sessionHistory" attributes are stored in memcached. Works independently from the chosen serialization strategy. transcoderFactoryClass (since 1.1, optional, default de.javakaffee.web.msm.JavaSerializationTranscoderFactory) The class name of the factory that creates the transcoder to use for serializing/deserializing sessions to/from memcached. The specified class must implement de.javakaffee.web.msm.TranscoderFactory and provide a no-args constructor. Other TranscoderFactory implementations are available through other packages/jars like msm-kryo-serializer, msm-xstream-serializer and msm-javolution-serializer (as describe above), those are listed and compared on SerializationStrategies. Available TranscoderFactory implementations: copyCollectionsForSerialization (since 1.1, optional, default false) A boolean value that specifies, if iterating over collection elements shall be done on a copy of the collection or on the collection itself. This configuration property must be supported by the serialization strategy specified with transcoderFactoryClass. Which strategy supports this feature can be seen in the column Copy Collections before serialization in the list of available serialization strategies. This feature and its motivation is described more deeply at SerializationStrategies#Concurrent_modifications_of_collections. customConverter (since 1.2, optional) Custom converter allow you to provide custom serialization of application specific types. Multiple custom converter class names are specified separated by comma (with optional space following the comma). Converter classes must be available in the classpath of the web application (place jars in WEB-INF/lib). Available converter implementations: enableStatistics (since 1.2, optional, default true) A boolean value that specifies, if statistics shall be gathered. For more info see the JMXStatistics page. enabled (since 1.4.0, optional, default true) Specifies if session storage in memcached is enabled or not, can also be changed at runtime via JMX. Only allowed in sticky mode. Configure loggingIf you want to enable fine grained / debug logging you can add de.javakaffee.web.msm.level=FINE to $CATALINA_HOME/conf/logging.properties. As the memcached-session-manager uses spymemcached also the logging hints of spymemcached might be interesting to you. A short summary how you can make spymemcached more silent:
CATALINA_OPTS="-Dnet.spy.log.LoggerImpl=net.spy.memcached.compat.log.SunLogger" # A handler's log level threshold can be set using SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST or ALL net.spy.memcached.level = WARNING # To make only the MemcachedConnection less verbose: #net.spy.memcached.MemcachedConnection.level = WARNING More info about logging in tomcat can be found in the tomcat logging documentation. |
Hi!
Which is the minimal required version of tomcat? Is tomcat 5.5 (Debian Lenny) supported?
Thanks ans best regards
I don't think that it will work with 5.5, but you might still try it. Let me know how it's going :-)
Cheers, Martin
Does not work in 5.5.30, I get "java.lang.ClassNotFoundException?: org.apache.juli.logging.LogFactory?". Any plans to backport the project to 5.5? Do you know how tight the code is coupled to Tomcat 6.x?
how to test the session has been shared
5.5 compatibility is represented by issue 63 : http://code.google.com/p/memcached-session-manager/issues/detail?id=63
How to test that a session has been shared: first create it on tomcat 1 (e.g. running at http://localhost:8080, and then load the page from the 2nd tomcat (e.g. running at http://localhost:8081) - as the session cookie is sent with the request to the 2nd tomcat the session will be loaded from memcached if the page gets the servlet session from the servlet request (e.g. just set/display some session attribute).
hi martin.grotzke. In my case,I used firefox to access tomcat1 to show sessionId in a JSP,then I access tomcat2 in the same firefox tab to show sessionId,but the sessionId is changed.I don't think it is work. So I try to modify parameter in nginx to set session stick,then it works.
how does memcached-session-manager deal with session?May be my session strategy is wrong.
@Field.Kao: either you request s.th. from tomcat or from nginx - not sure what you're really doing. Please let's continue this discussion on the mailing list: http://groups.google.com/group/memcached-session-manager Please provide more details about your setup and about what you're doing so that I can (mentally) reproduce your issue.
hi martin.grotzke,I think I was found the reason. I my case,I use tomcat1 with 172.16.10.41:8088 and tomcat2 with 172.16.10.76:8080,they shared session via memcached. And I use nginx to balance tomcat1 and tomcat2 via www.some.com. I access 172.16.10.41:8088,the sessionId is always 295F1601A37C1BB26DC292F86BCA00EA-n1. I access 172.16.10.76:8080,the sessionId is always D0BA06030D966314761359CE0C5A0F95-n1.
finailly I access www.some.com,the sessionId is always 3212A03B49F2AC73A92744516FE41791-n1,it is serviced by nginx via tomcat1 and tomcat2,so the session is shared successful.
So when I access the same domain(www.some.com),they use the same session,and it works.But if the domain changed(41:8088->76:8080),the session will be different,so I can not see it works.
BTW:link http://groups.google.com/group/memcached-session-manager can not be accessd.
Thank you!
You're welcome, great that it's working for you now. It's right that the same session-cookie/session-id must be sent to the tomcats, otherwise session sharing/failover is not possible. Now I know what you meant with your question "how does memcached-session-manager deal with session?" :-)
The mailing list at http://groups.google.com/group/memcached-session-manager is accessable for me, I asume it was a temporary problem on your side.
hoho:) I just see "memcached-session-manager is designed just for sticky-sessions" in this page,but I configue nginx as stickness session,so it not work.It is the reason.
Is there a plan msm will support stickness session?
You can search the mailing list, this was once requested and I built a version to play with nonsticky sessions (jars are just attached to postings). Though, this does not yet exist as a separate branch.
But I just found that the msm sample app already got such a branch, so you could also check this: github.com/magro/msm-sample-webapp/tree/nonsticky-sessions
hi martin.grotzke,how to use apache/tomcat/memcached-session-manager config loadbalancer and Cluster.Use stickness session.Thanks
Hi JosenXu001?, unfortunately I'm not sure what you want to know exactly. Please ask on the mailing list ( http://groups.google.com/group/memcached-session-manager ), there you can also be a bit more verbose :-)
Hello! Can I use this lib to share session between two different tomcat applications also?
@flyaaway: sounds as if you're looking for a single sign-on solution, session-replication (memcached-session-manager in particular) is not targeting this.
I need your help. I configure sever.xml as your example ,and I have two tomcat in different servers and two memcache in another different servers. when I used session.getAttribute() in jsp,I found the same session id in two tomcats' log, but only could get the proper value from one tomcat where the session set attribute. In memcache server I found the proper value with the key of seesion id. I don't know why another tomcat couldn't get the session attribute with the same session id. please help me. Thanks a lot
Hi huicheng@china.com, please post questions like this on the mailing list http://groups.google.com/group/memcached-session-manager. There you can also provide some sample code/jsp.
Hi, Martin thank you for your reply, but I couldn't visit http://groups.google.com/group/memcached-session-manager because I'm in China and our government forbidden us to visit this mail group site. so could you tell me another way to contact with you and I can send my sample code/jsp to you. thanks a lot
I saw your post on the mailing list, great! If it's not easy for you to reach this you can also submit an issue and we discuss your issue this way. http://code.google.com/p/memcached-session-manager/issues/list
JBOSS 6 uses a modified version of tomcat 6. do you recon it is possible to use the mmemcached session manager with jboss?
Hi , I encounter this error.
java.net.ConnectException?: Connection refused
2012-03-17 12:46:22.046 WARN Mar 17, 2012 12:46:22 PM de.javakaffee.web.msm.MemcachedSessionService? setLockingMode INFO: Setting lockingMode to null Mar 17, 2012 12:46:22 PM de.javakaffee.web.msm.MemcachedSessionService? createTranscoderFactory INFO: Creating transcoder factory de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory? Mar 17, 2012 12:46:22 PM org.apache.catalina.startup.HostConfig? deployDescriptor SEVERE: Error deploying configuration descriptor host-manager.xml java.lang.NoClassDefFoundError?: de/javakaffee/kryoserializers/KryoReflectionFactorySupport?