准备工作
创建一个简单的web应用,名为session。其中有两个页面,分别如下所示:
  • 页面login.jsp
[html] view plaincopy
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  4. <html>
  5. <head>
  6. <title>登录页面</title>
  7. <meta http-equiv="pragma" content="no-cache">
  8. <meta http-equiv="cache-control" content="no-cache">
  9. <meta http-equiv="expires" content="0">
  10. <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
  11. <meta http-equiv="description" content="This is my page">
  12. </head>
  13. <body>
  14. <table bgcolor="#F8C3C3" border="1" borderColor="#FF0000"
  15. align="center" width="260" height="160">
  16. <tr>
  17. <td height="15" colspan="2" align="center"
  18. style="background-color: #000000; font-size: 28px; color: #FFFF00"><b>用户登录</b></td>
  19. </tr>
  20. <form method="post" action="login">
  21. <tr>
  22. <td width="80" align="center"><b>用户名</b></td>
  23. <td><input type="text" name="userName" value="" /></td>
  24. </tr>
  25. <tr>
  26. <td align="center"><b>密 码</b></td>
  27. <td><input type="password" name="password" value="" /></td>
  28. </tr>
  29. <tr>
  30. <td colspan="2" align="center" style="background-color: #000000;">
  31. <input type="submit" value="登 录" />  <input type="reset"
  32. value="重 置" />
  33. </td>
  34. </tr>
  35. </form>
  36. </table>
  37. </body>
  38. </html>
  • 登录成功页面success.jsp
[html] view plaincopy
  1. <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
  2. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  3. <html>
  4. <head>
  5. <title>登录成功页面</title>
  6. <meta http-equiv="pragma" content="no-cache">
  7. <meta http-equiv="cache-control" content="no-cache">
  8. <meta http-equiv="expires" content="0">
  9. <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
  10. <meta http-equiv="description" content="This is my page">
  11. </head>
  12. <%
  13. String userName = (String) request.getSession().getAttribute("userName");
  14. %>
  15. <body bgcolor="#000000">
  16. <table width="500" height="200" align="center" border="1"
  17. style="background-color: #000000;">
  18. <tr>
  19. <td align="center"
  20. style="background-color: #F8C3C3; color: #00FF00; font-weight: bold; font-size: 30px">
  21. 当前登录用户:<%=userName %>
  22. </td>
  23. </tr>
  24. </table>
  25. </body>
  26. </html>
还有一个Servlet,负责请求的转发,并设置session数据,如下所示:
[java] view plaincopy
  1. package org.shirdrn.cluster.tomcat.servlet;
  2. import java.io.IOException;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. import javax.servlet.ServletException;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. import org.apache.commons.logging.Log;
  10. import org.apache.commons.logging.LogFactory;
  11. public class LoginSevlet extends HttpServlet {
  12. private static final long serialVersionUID = 1L;
  13. private static final Log LOG = LogFactory.getLog(LoginSevlet.class);
  14. private static Map<String, String> accountDB = new HashMap<String, String>();
  15. static {
  16. accountDB.put("shirdrn", "123456");
  17. accountDB.put("admin", "999999");
  18. accountDB.put("dev", "000888");
  19. accountDB.put("007", "007007");
  20. }
  21. public LoginSevlet() {
  22. super();
  23. }
  24. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  25. this.doPost(request, response);
  26. }
  27. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  28. String userName = request.getParameter("userName");
  29. String password = request.getParameter("password");
  30. LOG.info("Raw input:userName=" + userName + ",password=" + password);
  31. if(userName!=null && password!=null
  32. && accountDB.containsKey(userName)
  33. && accountDB.get(userName).equals(password)) {
  34. LOG.info("Login;status=SUCCESS");
  35. request.getSession().setAttribute("userName", userName);
  36. request.getRequestDispatcher("success.jsp").forward(request, response);
  37. } else {
  38. LOG.info("Login;status=FAIL");
  39. request.getRequestDispatcher("login.jsp").forward(request, response);
  40. }
  41. }
  42. }
这里模拟了一个账号数据库,对用户的登录请求进行处理。
最后打成WAR包,部署到Tomcat集群中的每个结点上。

Memcached安装、配置、启动
在Ubuntu系统下,如果没有安装Memcached,可以执行如下命令进行安装:

[plain] view plaincopy
  1. sudo apt-get install memcached
然后,启动Memcached服务进程,这里,我启动了两个服务进程,分别监听端口11211、11311,启动命令如下所示:
[plain] view plaincopy
  1. sudo /usr/bin/memcached -m 64 -d -u memcache -p 11211 -l 192.168.1.104 -c 5000 -P /tmp/n1-memcached.pid
  2. sudo /usr/bin/memcached -m 64 -d -u memcache -p 11311 -l 192.168.1.104 -c 5000 -P /tmp/n2-memcached.pid
查询Memcached服务状态:
[plain] view plaincopy
  1. shirdrn@dev:~/servers/cluster/nginx_tomcat_memcached$ ps -ef | grep memcached
  2. memcache  1578     1  0 Jan25 ?        00:00:00 /usr/bin/memcached -m 64 -p 11211 -u memcache -l 127.0.0.1
  3. memcache  3300     1  0 Jan25 ?        00:00:00 /usr/bin/memcached -m 64 -d -u memcache -p 11211 -l 192.168.1.104 -c 5000 -P /tmp/n1-memcached.pid
  4. memcache  3308     1  0 00:00 ?        00:00:00 /usr/bin/memcached -m 64 -d -u memcache -p 11311 -l 192.168.1.104 -c 5000 -P /tmp/n2-memcached.pid
  5. shirdrn   3318  3095  0 00:00 pts/5    00:00:00 grep --color=auto memcached

Tomcat集群配置
Tomcat 集群配置,集群中各个结点通过共享存储在缓存Memcached中session来实现session的共享:如果有一台机器上的Tomcat服务停掉 了,对于其他对等服务器上的session数据仍然可以从Memcached缓存中读取,从而不会发生session丢失的问题。
对于满足这种配置的实现方案,可以在https://code.google.com/p/memcached-session-manager和https://spymemcached.googlecode.com上下载相关的jar文件。因为基于不同的序列化方案,可以有多种配置方法,下面是选择Javolution序列化框架,需要提供如下库文件:
  • https://memcached-session-manager.googlecode.com/files/memcached-session-manager-1.6.3.jar
  • https://memcached-session-manager.googlecode.com/files/memcached-session-manager-tc7-1.6.3.jar
  • https://memcached-session-manager.googlecode.com/files/msm-javolution-serializer-1.6.2.jar
  • http://memcached-session-manager.googlecode.com/svn/maven/javolution/javolution/5.4.3.1/javolution-5.4.3.1.jar
  • https://spymemcached.googlecode.com/files/spymemcached-2.8.4.jar
下载上述jar文件,拷贝到$CATALINA_HOME/lib目录下,然后需要配置$CATALINA_HOME/conf/server.xml文件。
Tomcat集群中,每个结点的$CATALINA_HOME/conf/server.xml基本配置都是相同的,不同配置内容分别如下:
  • 如果在同一台机器上,要保证各个服务端口不相冲突
  • <Manager>元素中failoverNodes属性值不同
例如,我们在同一台机器上配置了两个Tomcat服务器实例,所在目录分别为tomcat-1和tomcat-2,对应的conf/server.xml配置内容如下:
  • tomcat-1/conf/server.xml

[html] view plaincopy
  1. <?xml version='1.0' encoding='utf-8'?>
  2. <Server port="8085" shutdown="SHUTDOWN">
  3. <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  4. <Listener className="org.apache.catalina.core.JasperListener" />
  5. <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  6. <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  7. <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
  8. <GlobalNamingResources>
  9. <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase"
  10. description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
  11. pathname="conf/tomcat-users.xml" />
  12. </GlobalNamingResources>
  13. <Service name="Catalina">
  14. <Connector port="8088" protocol="HTTP/1.1" connectionTimeout="20000"
  15. redirectPort="8443" />
  16. <Connector port="8089" protocol="AJP/1.3" redirectPort="8443" />
  17. <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
  18. <Realm className="org.apache.catalina.realm.LockOutRealm">
  19. <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
  20. resourceName="UserDatabase" />
  21. </Realm>
  22. <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" deployOnStartup="true">
  23. <Context docBase="/home/shirdrn/servers/cluster/nginx_tomcat_memcached/webapps/session.war" path="/session" reloadable="true">
  24. <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
  25. memcachedNodes="n1:192.168.1.104:11211,n2:192.168.1.104:11311"
  26. failoverNodes="n1"
  27. requestUriIgnorePattern=".*\.(png|gif|jpg|css|js)$"
  28. sessionBackupAsync="false"
  29. sessionBackupTimeout="100"
  30. transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"
  31. copyCollectionsForSerialization="false" />
  32. </Context>
  33. <Valve className="org.apache.catalina.valves.AccessLogValve"
  34. directory="logs" prefix="localhost_access_log." suffix=".txt"
  35. pattern="%h %l %u %t "%r" %s %b" />
  36. </Host>
  37. </Engine>
  38. </Service>
  39. </Server>
这里面,failover的Memcached结点是n1,也就是说,如果tomcat-1和n1在同一台机器上的话,session数据会优先复制到存储到Memcached结点n2,这样即使n1所在的结点宕机了,n2所在结点仍然存储了之前的session数据。
  • tomcat-2/conf/server.xml
[html] view plaincopy
  1. <?xml version='1.0' encoding='utf-8'?>
  2. <Server port="9085" shutdown="SHUTDOWN">
  3. <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  4. <Listener className="org.apache.catalina.core.JasperListener" />
  5. <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  6. <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  7. <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
  8. <GlobalNamingResources>
  9. <Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase"
  10. description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
  11. pathname="conf/tomcat-users.xml" />
  12. </GlobalNamingResources>
  13. <Service name="Catalina">
  14. <Connector port="9088" protocol="HTTP/1.1" connectionTimeout="20000"
  15. redirectPort="9443" />
  16. <Connector port="9089" protocol="AJP/1.3" redirectPort="9443" />
  17. <Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat1">
  18. <Realm className="org.apache.catalina.realm.LockOutRealm">
  19. <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
  20. resourceName="UserDatabase" />
  21. </Realm>
  22. <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" deployOnStartup="true">
  23. <Context docBase="/home/shirdrn/servers/cluster/nginx_tomcat_memcached/webapps/session.war" path="/session" reloadable="true">
  24. <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
  25. memcachedNodes="n1:192.168.1.104:11211,n2:192.168.1.104:11311"
  26. failoverNodes="n2"
  27. requestUriIgnorePattern=".*\.(png|gif|jpg|css|js)$"
  28. sessionBackupAsync="false"
  29. sessionBackupTimeout="100"
  30. transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"
  31. copyCollectionsForSerialization="false" />
  32. </Context>
  33. <Valve className="org.apache.catalina.valves.AccessLogValve"
  34. directory="logs" prefix="localhost_access_log." suffix=".txt"
  35. pattern="%h %l %u %t "%r" %s %b" />
  36. </Host>
  37. </Engine>
  38. </Service>
  39. </Server>
和上面 类似,failover的Memcached结点是n2,也就是说,如果tomcat-2和n2在同一台机器上的话,Session数据会优先复制到存储 到Memcached结点n1,这样即使n2所在的结点宕机了,n1所在结点仍然存储了之前的Session数据。
上面的 配置实现了Tomcat集群中,通过Memcached实现了Sticky Session(粘性Session),主要是通过配置failover结点来达到目的的。如果采用Non-sticky Session方式,就不需要考虑failover的问题,详细配置扩参考文档(https://code.google.com/p/memcached-session-manager/wiki/SetupAndConfiguration),下面截取一个片段:

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>
分别启动tomcat-1和tomcat-2,如下所示:

[plain] view plaincopy
  1. shirdrn@dev:~/servers/cluster/nginx_tomcat_memcached$ tomcat-1/bin/catalina.sh start
  2. Using CATALINA_BASE:   /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-1
  3. Using CATALINA_HOME:   /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-1
  4. Using CATALINA_TMPDIR: /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-1/temp
  5. Using JRE_HOME:        /home/hadoop/installation/jdk1.6.0_30
  6. Using CLASSPATH:       /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-1/bin/bootstrap.jar:/home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-1/bin/tomcat-juli.jar
  7. shirdrn@dev:~/servers/cluster/nginx_tomcat_memcached$ tomcat-2/bin/catalina.sh start
  8. Using CATALINA_BASE:   /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-2
  9. Using CATALINA_HOME:   /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-2
  10. Using CATALINA_TMPDIR: /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-2/temp
  11. Using JRE_HOME:        /home/hadoop/installation/jdk1.6.0_30
  12. Using CLASSPATH:       /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-2/bin/bootstrap.jar:/home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-2/bin/tomcat-juli.jar
可以查看两个tomcat的启动日志,对比一下:
  • tomcat-1的日志
[plain] view plaincopy
  1. shirdrn@dev:~/servers/cluster/nginx_tomcat_memcached$ tail -100f tomcat-1/logs/catalina.out
  2. Jan 26, 2013 12:03:25 AM org.apache.catalina.core.AprLifecycleListener init
  3. INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /home/hadoop/installation/jdk1.6.0_30/jre/lib/i386/client:/home/hadoop/installation/jdk1.6.0_30/jre/lib/i386:/home/hadoop/installation/jdk1.6.0_30/jre/../lib/i386:/usr/java/packages/lib/i386:/lib:/usr/lib
  4. Jan 26, 2013 12:03:26 AM org.apache.coyote.AbstractProtocol init
  5. INFO: Initializing ProtocolHandler ["http-bio-8088"]
  6. Jan 26, 2013 12:03:26 AM org.apache.coyote.AbstractProtocol init
  7. INFO: Initializing ProtocolHandler ["ajp-bio-8089"]
  8. Jan 26, 2013 12:03:26 AM org.apache.catalina.startup.Catalina load
  9. INFO: Initialization processed in 1743 ms
  10. Jan 26, 2013 12:03:26 AM org.apache.catalina.core.StandardService startInternal
  11. INFO: Starting service Catalina
  12. Jan 26, 2013 12:03:26 AM org.apache.catalina.core.StandardEngine startInternal
  13. INFO: Starting Servlet Engine: Apache Tomcat/7.0.26
  14. Jan 26, 2013 12:03:27 AM de.javakaffee.web.msm.MemcachedSessionService startInternal
  15. INFO: MemcachedSessionService starts initialization... (configured nodes definition n1:192.168.1.104:11211,n2:192.168.1.104:11311, failover nodes n1)
  16. 2013-01-26 00:03:27.441 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=/192.168.1.104:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
  17. 2013-01-26 00:03:27.442 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=/192.168.1.104:11311, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
  18. Jan 26, 2013 12:03:27 AM de.javakaffee.web.msm.RequestTrackingHostValve <init>
  19. INFO: Setting ignorePattern to .*\.(png|gif|jpg|css|js)$
  20. 2013-01-26 00:03:27.459 INFO net.spy.memcached.MemcachedConnection:  Connection state changed for sun.nio.ch.SelectionKeyImpl@5b0668
  21. 2013-01-26 00:03:27.460 INFO net.spy.memcached.MemcachedConnection:  Connection state changed for sun.nio.ch.SelectionKeyImpl@1d5a0
  22. Jan 26, 2013 12:03:27 AM de.javakaffee.web.msm.MemcachedSessionService setLockingMode
  23. INFO: Setting lockingMode to null
  24. Jan 26, 2013 12:03:27 AM de.javakaffee.web.msm.MemcachedSessionService createTranscoderFactory
  25. INFO: Creating transcoder factory de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory
  26. Jan 26, 2013 12:03:27 AM de.javakaffee.web.msm.MemcachedSessionService startInternal
  27. INFO: MemcachedSessionService finished initialization, sticky true, operation timeout 1000, with node ids [n2] and failover node ids [n1]
  28. Jan 26, 2013 12:03:27 AM org.apache.catalina.startup.HostConfig deployDirectory
  29. INFO: Deploying web application directory /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-1/webapps/host-manager
  30. Jan 26, 2013 12:03:27 AM org.apache.catalina.startup.HostConfig deployDirectory
  31. INFO: Deploying web application directory /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-1/webapps/manager
  32. Jan 26, 2013 12:03:27 AM org.apache.catalina.startup.HostConfig deployDirectory
  33. INFO: Deploying web application directory /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-1/webapps/docs
  34. Jan 26, 2013 12:03:27 AM org.apache.catalina.startup.HostConfig deployDirectory
  35. INFO: Deploying web application directory /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-1/webapps/examples
  36. Jan 26, 2013 12:03:28 AM org.apache.catalina.startup.HostConfig deployDirectory
  37. INFO: Deploying web application directory /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-1/webapps/ROOT
  38. Jan 26, 2013 12:03:28 AM org.apache.coyote.AbstractProtocol start
  39. INFO: Starting ProtocolHandler ["http-bio-8088"]
  40. Jan 26, 2013 12:03:28 AM org.apache.coyote.AbstractProtocol start
  41. INFO: Starting ProtocolHandler ["ajp-bio-8089"]
  42. Jan 26, 2013 12:03:28 AM org.apache.catalina.startup.Catalina start
  43. INFO: Server startup in 1487 ms
  • tomcat-2的日志
[plain] view plaincopy
  1. shirdrn@dev:~/servers/cluster/nginx_tomcat_memcached$ tail -100f tomcat-2/logs/catalina.out
  2. Jan 26, 2013 12:04:34 AM org.apache.catalina.core.AprLifecycleListener init
  3. INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /home/hadoop/installation/jdk1.6.0_30/jre/lib/i386/client:/home/hadoop/installation/jdk1.6.0_30/jre/lib/i386:/home/hadoop/installation/jdk1.6.0_30/jre/../lib/i386:/usr/java/packages/lib/i386:/lib:/usr/lib
  4. Jan 26, 2013 12:04:34 AM org.apache.coyote.AbstractProtocol init
  5. INFO: Initializing ProtocolHandler ["http-bio-9088"]
  6. Jan 26, 2013 12:04:34 AM org.apache.coyote.AbstractProtocol init
  7. INFO: Initializing ProtocolHandler ["ajp-bio-9089"]
  8. Jan 26, 2013 12:04:34 AM org.apache.catalina.startup.Catalina load
  9. INFO: Initialization processed in 742 ms
  10. Jan 26, 2013 12:04:34 AM org.apache.catalina.core.StandardService startInternal
  11. INFO: Starting service Catalina
  12. Jan 26, 2013 12:04:34 AM org.apache.catalina.core.StandardEngine startInternal
  13. INFO: Starting Servlet Engine: Apache Tomcat/7.0.26
  14. Jan 26, 2013 12:05:07 AM org.apache.catalina.util.SessionIdGenerator createSecureRandom
  15. INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [33,094] milliseconds.
  16. Jan 26, 2013 12:05:07 AM de.javakaffee.web.msm.MemcachedSessionService startInternal
  17. INFO: MemcachedSessionService starts initialization... (configured nodes definition n1:192.168.1.104:11211,n2:192.168.1.104:11311, failover nodes n2)
  18. 2013-01-26 00:05:07.873 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=/192.168.1.104:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
  19. 2013-01-26 00:05:07.876 INFO net.spy.memcached.MemcachedConnection:  Added {QA sa=/192.168.1.104:11311, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
  20. Jan 26, 2013 12:05:07 AM de.javakaffee.web.msm.RequestTrackingHostValve <init>
  21. INFO: Setting ignorePattern to .*\.(png|gif|jpg|css|js)$
  22. 2013-01-26 00:05:07.896 INFO net.spy.memcached.MemcachedConnection:  Connection state changed for sun.nio.ch.SelectionKeyImpl@701a27
  23. 2013-01-26 00:05:07.897 INFO net.spy.memcached.MemcachedConnection:  Connection state changed for sun.nio.ch.SelectionKeyImpl@1d5a0
  24. Jan 26, 2013 12:05:07 AM de.javakaffee.web.msm.MemcachedSessionService setLockingMode
  25. INFO: Setting lockingMode to null
  26. Jan 26, 2013 12:05:07 AM de.javakaffee.web.msm.MemcachedSessionService createTranscoderFactory
  27. INFO: Creating transcoder factory de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory
  28. Jan 26, 2013 12:05:07 AM de.javakaffee.web.msm.MemcachedSessionService startInternal
  29. INFO: MemcachedSessionService finished initialization, sticky true, operation timeout 1000, with node ids [n1] and failover node ids [n2]
  30. Jan 26, 2013 12:05:08 AM org.apache.catalina.startup.HostConfig deployDirectory
  31. INFO: Deploying web application directory /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-2/webapps/host-manager
  32. Jan 26, 2013 12:05:08 AM org.apache.catalina.startup.HostConfig deployDirectory
  33. INFO: Deploying web application directory /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-2/webapps/manager
  34. Jan 26, 2013 12:05:08 AM org.apache.catalina.startup.HostConfig deployDirectory
  35. INFO: Deploying web application directory /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-2/webapps/docs
  36. Jan 26, 2013 12:05:08 AM org.apache.catalina.startup.HostConfig deployDirectory
  37. INFO: Deploying web application directory /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-2/webapps/examples
  38. Jan 26, 2013 12:05:08 AM org.apache.catalina.startup.HostConfig deployDirectory
  39. INFO: Deploying web application directory /home/shirdrn/servers/cluster/nginx_tomcat_memcached/tomcat-2/webapps/ROOT
  40. Jan 26, 2013 12:05:08 AM org.apache.coyote.AbstractProtocol start
  41. INFO: Starting ProtocolHandler ["http-bio-9088"]
  42. Jan 26, 2013 12:05:08 AM org.apache.coyote.AbstractProtocol start
  43. INFO: Starting ProtocolHandler ["ajp-bio-9089"]
  44. Jan 26, 2013 12:05:08 AM org.apache.catalina.startup.Catalina start
  45. INFO: Server startup in 34163 ms
已经成功启动了。
Nginx安装、配置、启动
在Ubuntu系统下,如果没有安装Nginx,可以执行如下命令进行安装:

[plain] view plaincopy
  1. sudo apt-get install nginx
默认情况下,Nginx使用默认的配置文件/etc/nginx/nginx.conf,该配置文件直接包含了虚拟目录配置文件/etc/nginx/sites-available/default,修改该文件的内容为,如下所示:
[plain] view plaincopy
  1. # You may add here your
  2. # server {
  3. #     ...
  4. # }
  5. # statements for each of your virtual hosts to this file
  6. ##
  7. # You should look at the following URL's in order to grasp a solid understanding
  8. # of Nginx configuration files in order to fully unleash the power of Nginx.
  9. # http://wiki.nginx.org/Pitfalls
  10. # http://wiki.nginx.org/QuickStart
  11. # http://wiki.nginx.org/Configuration
  12. #
  13. # Generally, you will want to move this file somewhere, and start with a clean
  14. # file but keep this around for reference. Or just disable in sites-enabled.
  15. #
  16. # Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
  17. ##
  18. upstream dev.shirdrn.org {
  19. server 192.168.1.104:8088 weight=1;
  20. server 192.168.1.104:9088 weight=1;
  21. }
  22. server {
  23. #listen   80; ## listen for ipv4; this line is default and implied
  24. #listen   [::]:80 default ipv6only=on; ## listen for ipv6
  25. root /usr/share/nginx/www/session;  # session是我们配置的虚拟目录,实际直接指向Tomcat下名为session的web应用
  26. index index.html index.htm;
  27. # Make site accessible from http://localhost/
  28. #######     server_name localhost;
  29. server_name dev.shirdrn.org; # Nginx服务所在主机
  30. charset utf-8;
  31. location / {
  32. proxy_pass     http://dev.shirdrn.org; #直接代理tomcat集群
  33. proxy_set_header  X-Real-IP  $remote_addr;
  34. client_max_body_size  100m;
  35. # First attempt to serve request as file, then
  36. # as directory, then fall back to index.html
  37. #######          try_files $uri $uri/ /index.html;
  38. # Uncomment to enable naxsi on this location
  39. # include /etc/nginx/naxsi.rules
  40. }
  41. location ~ ^/(WEB-INF)/ { # 禁止访问Tomcat下web应用的WEB-INF目录下的资源
  42. deny all;
  43. }
  44. location /doc/ {
  45. alias /usr/share/doc/;
  46. autoindex on;
  47. allow 127.0.0.1;
  48. deny all;
  49. }
  50. # Only for nginx-naxsi : process denied requests
  51. #location /RequestDenied {
  52. # For example, return an error code
  53. #return 418;
  54. #}
  55. #error_page 404 /404.html;
  56. # redirect server error pages to the static page /50x.html
  57. #
  58. #error_page 500 502 503 504 /50x.html;
  59. #location = /50x.html {
  60. #     root /usr/share/nginx/www;
  61. #}
  62. # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
  63. #
  64. #location ~ \.php$ {
  65. #     fastcgi_split_path_info ^(.+\.php)(/.+)$;
  66. #     # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
  67. #
  68. #     # With php5-cgi alone:
  69. #     fastcgi_pass 127.0.0.1:9000;
  70. #     # With php5-fpm:
  71. #     fastcgi_pass unix:/var/run/php5-fpm.sock;
  72. #     fastcgi_index index.php;
  73. #     include fastcgi_params;
  74. #}
  75. # deny access to .htaccess files, if Apache's document root
  76. # concurs with nginx's one
  77. #
  78. #location ~ /\.ht {
  79. #     deny all;
  80. #}
  81. }
  82. # another virtual host using mix of IP-, name-, and port-based configuration
  83. #
  84. #server {
  85. #     listen 8000;
  86. #     listen somename:8080;
  87. #     server_name somename alias another.alias;
  88. #     root html;
  89. #     index index.html index.htm;
  90. #
  91. #     location / {
  92. #          try_files $uri $uri/ /index.html;
  93. #     }
  94. #}
  95. # HTTPS server
  96. #
  97. #server {
  98. #     listen 443;
  99. #     server_name localhost;
  100. #
  101. #     root html;
  102. #     index index.html index.htm;
  103. #
  104. #     ssl on;
  105. #     ssl_certificate cert.pem;
  106. #     ssl_certificate_key cert.key;
  107. #
  108. #     ssl_session_timeout 5m;
  109. #
  110. #     ssl_protocols SSLv3 TLSv1;
  111. #     ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
  112. #     ssl_prefer_server_ciphers on;
  113. #
  114. #     location / {
  115. #          try_files $uri $uri/ /index.html;
  116. #     }
  117. #}
上面配置中根目录为/usr/share/nginx/www,因为我们使用到了一个虚拟目录来对应Tomcat下部署的web应用的path,所以需要在/usr/share/nginx/www下面创建这个对应的虚拟目录:
[plain] view plaincopy
  1. shirdrn@dev:~/servers/cluster/nginx_tomcat_memcached$ sudo mkdir /usr/share/nginx/www/session
最后,可以启动Nginx服务器,执行如下命令:
[plain] view plaincopy
  1. shirdrn@dev:~$ sudo /etc/init.d/nginx start
查询Nginx服务启动状态:
[plain] view plaincopy
  1. shirdrn@dev:~/servers/cluster/nginx_tomcat_memcached$ sudo ps -ef | grep nginx
  2. root      3199     1  0 Jan25 ?        00:00:00 nginx: master process /usr/sbin/nginx
  3. www-data  3200  3199  0 Jan25 ?        00:00:00 nginx: worker process
  4. www-data  3201  3199  0 Jan25 ?        00:00:00 nginx: worker process
  5. www-data  3202  3199  0 Jan25 ?        00:00:00 nginx: worker process
  6. www-data  3203  3199  0 Jan25 ?        00:00:00 nginx: worker process
  7. shirdrn   3327  3095  0 00:01 pts/5    00:00:00 grep --color=auto nginx
这是就可以通过Nginx访问(代理)Web应用首页了。
集群验证
上面配置完成,服务都已经启动成功,可以直接请求链接http://dev.shirdrn.org/session,就会直接访问部署在Tomcat服务器上的Java Web应用,看到登录页面。
使用前面准备的Web应用session中账号数据进行模拟登录,就可以查看Memcached缓存的数据:
  • telnet 192.168.1.104 11211
telnet到memcached服务端口,查看缓存统计数据。

[plain] view plaincopy
  1. shirdrn@dev:~$ telnet 192.168.1.104 11211
  2. Trying 192.168.1.104...
  3. Connected to 192.168.1.104.
  4. Escape character is '^]'.
  5. ERROR
  6. stats
  7. STAT pid 3300
  8. STAT uptime 2148
  9. STAT time 1359131741
  10. STAT version 1.4.13
  11. STAT libevent 2.0.16-stable
  12. STAT pointer_size 32
  13. STAT rusage_user 0.052003
  14. STAT rusage_system 0.084005
  15. STAT curr_connections 7
  16. STAT total_connections 9
  17. STAT connection_structures 8
  18. STAT reserved_fds 20
  19. STAT cmd_get 23
  20. STAT cmd_set 6
  21. STAT cmd_flush 0
  22. STAT cmd_touch 0
  23. STAT get_hits 2
  24. STAT get_misses 21
  25. STAT delete_misses 0
  26. STAT delete_hits 0
  27. STAT incr_misses 0
  28. STAT incr_hits 0
  29. STAT decr_misses 0
  30. STAT decr_hits 0
  31. STAT cas_misses 0
  32. STAT cas_hits 0
  33. STAT cas_badval 0
  34. STAT touch_hits 0
  35. STAT touch_misses 0
  36. STAT auth_cmds 0
  37. STAT auth_errors 0
  38. STAT bytes_read 2675
  39. STAT bytes_written 2835
  40. STAT limit_maxbytes 67108864
  41. STAT accepting_conns 1
  42. STAT listen_disabled_num 0
  43. STAT threads 4
  44. STAT conn_yields 0
  45. STAT hash_power_level 16
  46. STAT hash_bytes 262144
  47. STAT hash_is_expanding 0
  48. STAT expired_unfetched 0
  49. STAT evicted_unfetched 0
  50. STAT bytes 858
  51. STAT curr_items 2
  52. STAT total_items 6
  53. STAT evictions 0
  54. STAT reclaimed 0
  55. END
  • telnet 192.168.1.104 11311
[plain] view plaincopy
  1. shirdrn@dev:~$ telnet 192.168.1.104 11311
  2. Trying 192.168.1.104...
  3. Connected to 192.168.1.104.
  4. Escape character is '^]'.
  5. stats
  6. STAT pid 3308
  7. STAT uptime 2398
  8. STAT time 1359132000
  9. STAT version 1.4.13
  10. STAT libevent 2.0.16-stable
  11. STAT pointer_size 32
  12. STAT rusage_user 0.004000
  13. STAT rusage_system 0.128008
  14. STAT curr_connections 7
  15. STAT total_connections 9
  16. STAT connection_structures 8
  17. STAT reserved_fds 20
  18. STAT cmd_get 1
  19. STAT cmd_set 2
  20. STAT cmd_flush 0
  21. STAT cmd_touch 0
  22. STAT get_hits 0
  23. STAT get_misses 1
  24. STAT delete_misses 1
  25. STAT delete_hits 0
  26. STAT incr_misses 0
  27. STAT incr_hits 0
  28. STAT decr_misses 0
  29. STAT decr_hits 0
  30. STAT cas_misses 0
  31. STAT cas_hits 0
  32. STAT cas_badval 0
  33. STAT touch_hits 0
  34. STAT touch_misses 0
  35. STAT auth_cmds 0
  36. STAT auth_errors 0
  37. STAT bytes_read 644
  38. STAT bytes_written 2109
  39. STAT limit_maxbytes 67108864
  40. STAT accepting_conns 1
  41. STAT listen_disabled_num 0
  42. STAT threads 4
  43. STAT conn_yields 0
  44. STAT hash_power_level 16
  45. STAT hash_bytes 262144
  46. STAT hash_is_expanding 0
  47. STAT expired_unfetched 1
  48. STAT evicted_unfetched 0
  49. STAT bytes 0
  50. STAT curr_items 0
  51. STAT total_items 2
  52. STAT evictions 0
  53. STAT reclaimed 1
  54. END
我们可以停掉某个Tomcat服务,然后观察Session会话数据的复制过程,能够保证当前集群中的会话数据不丢失,另一个结点仍然能提供基于该存在Session的服务。
参考链接
  • https://code.google.com/p/memcached-session-manager
  • https://code.google.com/p/memcached-session-manager/wiki/SetupAndConfiguration
  • http://code.google.com/p/kryo/
  • http://wiki.ubuntu.org.cn/Nginx
  • http://www.iteye.com/topic/676347

转载于:https://www.cnblogs.com/interdrp/p/3733465.html

Nginx+Memcached+Tomcat集群配置实践(Sticky Session)相关推荐

  1. 配置集群Nginx+Memcached+Tomcat集群配置

    上班之余抽点时间出来写写博文,希望对新接触的朋友有帮助.今天在这里和大家一起学习一下配置集群 1.   Nginx Nginx是通过将多个Web Server绑定到同一个IP地址下,以实现多个WebS ...

  2. Nginx以及通过Nginx实现tomcat集群配置与负载均衡

    Nginx简介 启动,停止,和重新加载配置文件命令 Nginx功能 正向代理和反向代理的区别 反向代理 负载均衡 1.RR(默认) 2.权重 3.ip_hash 4.fair(第三方) 5.url_h ...

  3. Windows7 + Nginx + Memcached + Tomcat 集群 session 共享

    一,环境说明 操作系统是Windows7家庭版(有点不专业哦,呵呵!),JDK是1.6的版本, Tomcat是apache-tomcat-6.0.35-windows-x86,下载链接:http:// ...

  4. Nginx SSL+tomcat集群配置SSL,ngnix配置SSL后js/css访问出现404

    最近在做一个项目, 架构上使用了 Nginx +tomcat 集群, 且nginx下配置了SSL,tomcat no SSL,项目使用https协议 但是,明明是https url请求,发现 log里 ...

  5. linux环境下通过nginx实现tomcat集群

    2019独角兽企业重金招聘Python工程师标准>>> linux环境下通过nginx实现tomcat集群 安装nginx之前需要pcre依赖和jvm-remote补丁 一.准备如下 ...

  6. nginx+双tomcat集群负载均衡(一台机器)

    nginx简介 Nginx ("engine x") 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器. Nginx 是由 Igor ...

  7. window xp Apache与Tomcat集群配置--转载

    转载地址:http://www.cnblogs.com/obullxl/archive/2011/06/09/apache-tomcat-cluster-config.html 一. 环境说明 Win ...

  8. 大数据互联网架构 tomcat集群配置时三个端口的作用

    tomcat集群配置时三个端口的作用 在配置多个tomcat时需要同时配置这三个端口 Connector用于监听请求 protocol: http/1.1协议 , 用于监听浏览器发送的请求 , 设置成 ...

  9. Apache + Tomcat集群配置详解(1)

    Apache + Tomcat集群配置详解(1) 一.软件准备 Apache 2.2 : http://httpd.apache.org/download.cgi,下载msi安装程序,选择no ssl ...

最新文章

  1. Spring Boot 2.x基础教程:快速入门
  2. session一致性架构设计
  3. 基于docker容器下mongodb 4.0.0 的Replica Sets+Sharded Cluster集群
  4. 使用 Subversion (SVN) 的方式来访问 Github
  5. 随想录(安全关键系统和rtos)
  6. 情爱宝典:识破男女间的“放电”信号
  7. 顶级的CSS和Javascript动画框架推荐
  8. JAVA 基础语法(五)——数组
  9. 调用接口获得地区,再根据地区判断对应编号
  10. VBA实例6 CorelDraw 批量生成设备位号、连续编号
  11. 挂茶馆热血传奇私服辅助开发教程
  12. 阿里云CentOS环境之docker安装,启动,加速器,docker-compose(十四)
  13. NMDS非度量多维尺度分析
  14. 通过poi导出带图片的Excel表格
  15. Java验证图片格式
  16. 为什么 MongoDB 使用 B 树?
  17. 云巡店php源码,云巡店™〡连锁版正式上线开放注册〡《系统使用手册 1.0》
  18. 在 pygame 中好好玩玩精灵,滚雪球学 Python 游戏番
  19. html好友页面,好友列表.html
  20. Java中命令行调用大坑

热门文章

  1. 利用市场推广快速建立人脉关系
  2. 何谓直销(Direct Selling)?
  3. 作为HR,最近简历筛得有点心酸,36岁离异的,37岁未婚的,42岁离职照顾生病母亲重新找工作的.........
  4. 028、FLV视频转MP3音频文件
  5. java 计算器——加减乘除,键盘输入和鼠标输入
  6. eis电子防抖好还是光学防抖好_Redmi K30 Pro相机系统公布 6400万配双OIS光学防抖
  7. 数据库中间件:Mycat 权威指南+Mycat 实战笔记,双管齐下
  8. 你和大神之间只差一个高效工具
  9. LoveChat独立部署即时通讯IM 私人部署 完善的售后体系
  10. 二阶椭圆型第一边值问题的数值解法(五点差分格式和有限体积法)附matlab代码