天天看点

基于Tomcat构建LNMT架构的网站并实现Session保持

简介

LNMT=Linux+Nginx+MySQL+Tomcat;

Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器;

在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选;

架构需求

Tomcat实现JSP动态请求解析的基本架构

<a href="http://s3.51cto.com/wyfs02/M01/26/92/wKioL1NrqMnjx4uUAAKZ_TrMPLU912.jpg" target="_blank"></a>

说明:由后端Tomcat负责解析动态jsp请求,但为了提高响应性能,在同一主机内配置Nginx做反向代理,转发所有请求至tomcat即可;

完整的LNMT架构设计

<a href="http://s3.51cto.com/wyfs02/M00/26/92/wKiom1NrqReyIsVnAAXyNugPRuA080.jpg" target="_blank"></a>

说明:本篇博客主要讲解单台Haproxy到后端多台Tomcat服务器的实现;

安装配置

Tomcat安装配置

安装JDK

1

2

3

4

5

<code># rpm -ivh jdk-7u9-linux-x64.rpm</code>

<code># vi /etc/profile.d/java.sh</code>

<code>    </code><code>export</code> <code>JAVA_HOME=</code><code>/usr/java/latest</code>

<code>    </code><code>export</code> <code>PATH=$JAVA_HOME</code><code>/bin</code><code>:$PATH</code>

<code># . /etc/profile.d/java.sh</code>

安装Tomcat

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

<code># tar xf apache-tomcat-7.0.42.tar.gz -C /usr/local/</code>

<code># cd /usr/local/</code>

<code># ln -sv apache-tomcat-7.0.42/ tomcat</code>

<code># vi /etc/profile.d/tomcat.sh</code>

<code>    </code><code>export</code> <code>CATALINA_HOME=</code><code>/usr/local/tomcat</code>

<code>    </code><code>export</code> <code>PATH=$CATALINA_HOME</code><code>/bin</code><code>:$PATH</code>

<code># . /etc/profile.d/tomcat.sh</code>

<code># 编写服务脚本</code>

<code># vi /etc/init.d/tomcat</code>

<code>#!/bin/sh</code>

<code># Tomcat init script for Linux.</code>

<code>#</code>

<code># chkconfig: 2345 96 14</code>

<code># description: The Apache Tomcat servlet/JSP container.</code>

<code># JAVA_OPTS='-Xms64m -Xmx128m'</code>

<code>JAVA_HOME=</code><code>/usr/java/latest</code>

<code>CATALINA_HOME=</code><code>/usr/local/tomcat</code>

<code>export</code> <code>JAVA_HOME CATALINA_HOME</code>

<code>case</code> <code>$1 </code><code>in</code>

<code>start)</code>

<code>  </code><code>exec</code> <code>$CATALINA_HOME</code><code>/bin/catalina</code><code>.sh start ;;</code>

<code>stop)</code>

<code>  </code><code>exec</code> <code>$CATALINA_HOME</code><code>/bin/catalina</code><code>.sh stop;;</code>

<code>restart)</code>

<code>  </code><code>$CATALINA_HOME</code><code>/bin/catalina</code><code>.sh stop</code>

<code>  </code><code>sleep</code> <code>2</code>

<code>*)</code>

<code>  </code><code>echo</code> <code>"Usage: `basename $0` {start|stop|restart}"</code>

<code>  </code><code>exit</code> <code>1</code>

<code>  </code><code>;;</code>

<code>esac</code>

<code># chmod +x /etc/init.d/tomcat</code>

配置Tomcat

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

<code># cd /usr/local/tomcat/conf</code>

<code># vi server.xml</code>

<code>&lt;?xml version=</code><code>'1.0'</code> <code>encoding=</code><code>'utf-8'</code><code>?&gt;</code>

<code>&lt;Server port=</code><code>"8005"</code> <code>shutdown</code><code>=</code><code>"SHUTDOWN"</code><code>&gt;</code>

<code>  </code><code>&lt;Listener className=</code><code>"org.apache.catalina.core.AprLifecycleListener"</code> <code>SSLEngine=</code><code>"on"</code> <code>/&gt;</code>

<code>  </code><code>&lt;Listener className=</code><code>"org.apache.catalina.core.JasperListener"</code> <code>/&gt;</code>

<code>  </code><code>&lt;Listener className=</code><code>"org.apache.catalina.core.JreMemoryLeakPreventionListener"</code> <code>/&gt;</code>

<code>  </code><code>&lt;Listener className=</code><code>"org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"</code> <code>/&gt;</code>

<code>  </code><code>&lt;Listener className=</code><code>"org.apache.catalina.core.ThreadLocalLeakPreventionListener"</code> <code>/&gt;</code>

<code>  </code><code>&lt;GlobalNamingResources&gt;</code>

<code>    </code><code>&lt;Resource name=</code><code>"UserDatabase"</code> <code>auth=</code><code>"Container"</code>

<code>              </code><code>type</code><code>=</code><code>"org.apache.catalina.UserDatabase"</code>

<code>              </code><code>description=</code><code>"User database that can be updated and saved"</code>

<code>              </code><code>factory=</code><code>"org.apache.catalina.users.MemoryUserDatabaseFactory"</code>

<code>              </code><code>pathname=</code><code>"conf/tomcat-users.xml"</code> <code>/&gt;</code>

<code>  </code><code>&lt;</code><code>/GlobalNamingResources</code><code>&gt;</code>

<code>  </code><code>&lt;Service name=</code><code>"Catalina"</code><code>&gt;</code>

<code>    </code><code>&lt;Connector port=</code><code>"9000"</code> <code>protocol=</code><code>"HTTP/1.1"</code>    <code># 配置HTTP连接器监听9000端口</code>

<code>               </code><code>connectionTimeout=</code><code>"20000"</code>

<code>               </code><code>redirectPort=</code><code>"8443"</code> <code>/&gt;</code>

<code>    </code><code>&lt;Connector port=</code><code>"8009"</code> <code>protocol=</code><code>"AJP/1.3"</code> <code>redirectPort=</code><code>"8443"</code> <code>/&gt;</code>

<code>    </code><code>&lt;Engine name=</code><code>"Catalina"</code> <code>defaultHost=</code><code>"localhost"</code><code>&gt;</code>

<code>      </code><code>&lt;Realm className=</code><code>"org.apache.catalina.realm.LockOutRealm"</code><code>&gt;</code>

<code>        </code><code>&lt;Realm className=</code><code>"org.apache.catalina.realm.UserDatabaseRealm"</code>

<code>               </code><code>resourceName=</code><code>"UserDatabase"</code><code>/&gt;</code>

<code>      </code><code>&lt;</code><code>/Realm</code><code>&gt;</code>

<code>      </code><code>&lt;Host name=</code><code>"xxrenzhe.lnmmp.com"</code>  <code>appBase=</code><code>"webapps"</code> <code># 新增Host,配置相应的Context</code>

<code>            </code><code>unpackWARs=</code><code>"true"</code> <code>autoDeploy=</code><code>"true"</code><code>&gt;</code>

<code>            </code><code>&lt;Context path=</code><code>""</code> <code>docBase=</code><code>"lnmmpapp"</code> <code>/&gt; </code><code># 配置的应用程序目录是webapps/lnmmpapp</code>

<code>        </code><code>&lt;Valve className=</code><code>"org.apache.catalina.valves.AccessLogValve"</code> <code>directory=</code><code>"logs"</code>

<code>               </code><code>prefix=</code><code>"lnmmp_access_log."</code> <code>suffix=</code><code>".txt"</code>

<code>               </code><code>pattern=</code><code>"%h %l %u %t &amp;quot;%r&amp;quot; %s %b"</code> <code>/&gt;</code>

<code>      </code><code>&lt;</code><code>/Host</code><code>&gt;</code>

<code>      </code><code>&lt;Host name=</code><code>"localhost"</code>  <code>appBase=</code><code>"webapps"</code>

<code>               </code><code>prefix=</code><code>"localhost_access_log."</code> <code>suffix=</code><code>".txt"</code>

<code>    </code><code>&lt;</code><code>/Engine</code><code>&gt;</code>

<code>  </code><code>&lt;</code><code>/Service</code><code>&gt;</code>

<code>&lt;</code><code>/Server</code><code>&gt;</code>

<code># 创建应用程序相关目录</code>

<code># cd /usr/local/tomcat/webapps/</code>

<code># mkdir -pv lnmmpapp/WEB-INF/{classes,lib}</code>

<code># cd lnmmpapp</code>

<code># vi index.jsp # 编写首页文件</code>

<code>&lt;%@ page language=</code><code>"java"</code> <code>%&gt;</code>

<code>&lt;html&gt;</code>

<code>  </code><code>&lt;</code><code>head</code><code>&gt;&lt;title&gt;Tomcat1&lt;</code><code>/title</code><code>&gt;&lt;</code><code>/head</code><code>&gt;</code><code># 在Tomcat2主机上替换为Tomcat2</code>

<code>  </code><code>&lt;body&gt;</code>

<code>    </code><code>&lt;h1&gt;&lt;font color=</code><code>"red"</code><code>&gt;Tomcat1.lnmmp.com&lt;</code><code>/font</code><code>&gt;&lt;</code><code>/h1</code><code>&gt;</code><code>#  在Tomcat2主机上替换为Tomcat2.lnmmp.com,color修改为blue</code>

<code>    </code><code>&lt;table align=</code><code>"centre"</code> <code>border=</code><code>"1"</code><code>&gt;</code>

<code>      </code><code>&lt;</code><code>tr</code><code>&gt;</code>

<code>        </code><code>&lt;td&gt;Session ID&lt;</code><code>/td</code><code>&gt;</code>

<code>    </code><code>&lt;% session.setAttribute(</code><code>"lnmmp.com"</code><code>,</code><code>"lnmmp.com"</code><code>); %&gt;</code>

<code>        </code><code>&lt;td&gt;&lt;%= session.getId() %&gt;&lt;</code><code>/td</code><code>&gt;</code>

<code>      </code><code>&lt;</code><code>/tr</code><code>&gt;</code>

<code>        </code><code>&lt;td&gt;Created on&lt;</code><code>/td</code><code>&gt;</code>

<code>        </code><code>&lt;td&gt;&lt;%= session.getCreationTime() %&gt;&lt;</code><code>/td</code><code>&gt;</code>

<code>     </code><code>&lt;</code><code>/tr</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>/table</code><code>&gt;</code>

<code>  </code><code>&lt;</code><code>/body</code><code>&gt;</code>

<code>&lt;</code><code>/html</code><code>&gt;</code>

启动Tomcat服务

<code>chkconfig --add tomcat</code>

<code>service tomcat start</code>

Nginx配置

配置Nginx

<code># vi /etc/nginx/nginx.conf</code>

<code>worker_processes  2;</code>

<code>error_log  </code><code>/var/log/nginx/nginx</code><code>.error.log;</code>

<code>pid        </code><code>/var/run/nginx</code><code>.pid;</code>

<code>events {</code>

<code>    </code><code>worker_connections  1024;</code>

<code>}</code>

<code>http {</code>

<code>    </code><code>include       mime.types;</code>

<code>    </code><code>default_type  application</code><code>/octet-stream</code><code>;</code>

<code>    </code><code>log_format  main  </code><code>'$remote_addr - $remote_user [$time_local] "$request" '</code>

<code>                      </code><code>'$status $body_bytes_sent "$http_referer" '</code>

<code>                      </code><code>'"$http_user_agent" "$http_x_forwarded_for"'</code><code>;</code>

<code>    </code><code>sendfile        on;</code>

<code>    </code><code>keepalive_timeout  65;</code>

<code>    </code><code>fastcgi_cache_path </code><code>/www/cache</code> <code>levels=1:2 keys_zone=fcgicache:10m inactive=5m;</code>

<code>    </code><code>server {    </code><code># 处理前端发来的图片请求;</code>

<code>        </code><code>listen       4040;</code>

<code>        </code><code>server_name  xxrenzhe.lnmmp.com;</code>

<code>        </code><code>access_log  </code><code>/var/log/nginx/nginx-img</code><code>.access.log  main;</code>

<code>        </code><code>root </code><code>/www/lnmmp</code><code>.com;</code>

<code>        </code><code>valid_referers none blocked xxrenzhe.lnmmp.com *.lnmmp.com; </code><code># 配置一定的反盗链策略;</code>

<code>        </code><code>if</code> <code>($invalid_referer) {</code>

<code>            </code><code>rewrite ^/ http:</code><code>//xxrenzhe</code><code>.lnmmp.com</code><code>/404</code><code>.html;</code>

<code>        </code><code>}</code>

<code>    </code><code>}</code>

<code>    </code><code>server {</code>

<code>        </code><code>listen       80;    </code><code># 处理前端发来的静态请求;</code>

<code>        </code><code>access_log  </code><code>/var/log/nginx/nginx-static</code><code>.access.log  main;</code>

<code>        </code><code>location / {</code>

<code>            </code><code>root   </code><code>/www/lnmmp</code><code>.com;</code>

<code>            </code><code>index  index.php index.html index.htm;</code>

<code>        </code><code>gzip</code> <code>on;    </code><code># 对静态文件开启压缩传输功能;</code>

<code>        </code><code>gzip_comp_level 6;</code>

<code>        </code><code>gzip_buffers 16 8k;</code>

<code>        </code><code>gzip_http_version 1.1;</code>

<code>        </code><code>gzip_types text</code><code>/plain</code> <code>text</code><code>/css</code> <code>application</code><code>/x-javascript</code> <code>text</code><code>/xml</code> <code>application</code><code>/xml</code><code>;</code>

<code>        </code><code>gzip_disable msie6;</code>

<code>        </code><code>listen       8080;</code>

<code>        </code><code>access_log  </code><code>/var/log/nginx/nginx-tomcat</code><code>.access.log  main;</code>

<code>            </code><code>proxy_pass http:</code><code>//127</code><code>.0.0.1:9000;  </code><code># 将全部动态请求都转发至后端tomcat</code>

启动服务

<code>service nginx start</code>

Haproxy安装配置

<code># yum -y install haproxy</code>

<code># vi /etc/haproxy/haproxy.cfg</code>

<code>global</code>

<code>    </code><code>log         127.0.0.1 local2</code>

<code>    </code><code>chroot      </code><code>/var/lib/haproxy</code>

<code>    </code><code>pidfile     </code><code>/var/run/haproxy</code><code>.pid</code>

<code>    </code><code>maxconn     4000</code>

<code>    </code><code>user         haproxy</code>

<code>    </code><code>group       haproxy</code>

<code>    </code><code>daemon</code>

<code>defaults</code>

<code>    </code><code>mode                   http</code>

<code>    </code><code>log                     global</code>

<code>    </code><code>option                  httplog</code>

<code>    </code><code>option                  dontlognull</code>

<code>    </code><code>option http-server-close</code>

<code>    </code><code>option forwardfor except 127.0.0.0</code><code>/8</code>

<code>    </code><code>option                  redispatch</code>

<code>    </code><code>retries                 3</code>

<code>    </code><code>timeout http-request    10s</code>

<code>    </code><code>timeout queue           1m</code>

<code>    </code><code>timeout connect         10s</code>

<code>    </code><code>timeout client          1m</code>

<code>    </code><code>timeout server          1m</code>

<code>    </code><code>timeout http-keep-alive 10s</code>

<code>    </code><code>timeout check           10s</code>

<code>    </code><code>maxconn                 30000</code>

<code>listen stats    </code><code># 配置haproxy的状态信息页面</code>

<code>    </code><code>mode http</code>

<code>    </code><code>bind 0.0.0.0:1080</code>

<code>    </code><code>stats </code><code>enable</code>

<code>    </code><code>stats hide-version</code>

<code>    </code><code>stats uri     </code><code>/haproxyadmin</code><code>?stats</code>

<code>    </code><code>stats realm   Haproxy\ Statistics</code>

<code>    </code><code>stats auth    admin:admin</code>

<code>    </code><code>stats admin </code><code>if</code> <code>TRUE</code>

<code>frontend http-</code><code>in</code>

<code>    </code><code>bind *:80</code>

<code>    </code><code>log global</code>

<code>    </code><code>option httpclose</code>

<code>    </code><code>option logasap</code>

<code>    </code><code>option dontlognull</code>

<code>    </code><code>capture request  header Host len 20</code>

<code>    </code><code>capture request  header Referer len 60</code>

<code>    </code><code>acl url_img         path_beg       -i </code><code>/images</code>

<code>    </code><code>acl url_img          path_end       -i .jpg .jpeg .gif .png</code>

<code>    </code><code>acl url_dynamic      path_end       -i .jsp .</code><code>do</code>

<code>    </code><code>use_backend img_servers </code><code>if</code> <code>url_img </code><code># 图片请求发送至图片服务器;</code>

<code>    </code><code>use_backend dynamic_servers </code><code>if</code> <code>url_dynamic </code><code># JSP动态请求发送至Tomcat服务器;</code>

<code>    </code><code>default_backend static_servers    </code><code># 其余静态请求都发送至静态服务器;</code>

<code>backend img_servers</code>

<code>    </code><code>balance roundrobin</code>

<code>    </code><code>server img-srv1 192.168.0.25:4040 check maxconn 6000</code>

<code>    </code><code>server img-srv2 192.168.0.35:4040 check maxconn 6000</code>

<code>backend static_servers</code>

<code>    </code><code>cookie node insert nocache</code>

<code>    </code><code>option httpchk HEAD </code><code>/health_check</code><code>.html</code>

<code>    </code><code>server static-srv1 192.168.0.25:80 check maxconn 6000 cookie static-srv1</code>

<code>    </code><code>server static-srv2 192.168.0.35:80 check maxconn 6000 cookie static-srv2</code>

<code>backend dynamic_servers</code>

<code>    </code><code>server tomcat1 192.168.0.25:8080 check maxconn 1000</code>

<code>    </code><code>server tomcat2 192.168.0.35:8080 check maxconn 1000</code>

<code>service haproxy start</code>

本地DNS解析设置

<code>xxrenzhe.lnmmp.com A 172.16.25.109 </code><code># 配置为haproxy的IP地址即可</code>

访问验证

<a href="http://s3.51cto.com/wyfs02/M00/26/92/wKioL1Nrq1nB5OdXAALLOgv4fJM431.jpg" target="_blank"></a>

<a href="http://s3.51cto.com/wyfs02/M02/26/92/wKiom1Nrq6SCsO8mAALN8_JzTYI243.jpg" target="_blank"></a>

说明:由于前端Haproxy调度动态请求是roundrobin算法,故每次刷新都会轮询分配到不同的Tomcat节点上,且每次获得的session都是不一样的;

实现session绑定

将同一用户的请求调度至后端同一台Tomcat上,不至于一刷新就导致session丢失;

修改Tomcat配置

<code># vi /usr/local/tomcat/conf/server.xml # 修改如下行内容,添加jvmRoute字段</code>

<code>&lt;Engine name=</code><code>"Catalina"</code> <code>defaultHost=</code><code>"localhost"</code> <code>jvmRoute=</code><code>"tomcat1"</code><code>&gt; </code><code># 在Tomcat2上替换为tomcat2</code>

修改Haproxy配置

<code># vi /etc/haproxy/haproxy.cfg # 为后端动态节点添加cookie绑定机制</code>

<code>    </code><code>server tomcat1 192.168.0.25:8080 check maxconn 1000 cookie tomcat1</code>

<code>    </code><code>server tomcat2 192.168.0.35:8080 check maxconn 1000 cookie tomcat1</code>

<a href="http://s3.51cto.com/wyfs02/M01/26/92/wKioL1NrrEOyj3ffAALgfNO9W3A279.jpg" target="_blank"></a>

说明:当第一次访问成功后,再次刷新并不会改变分配的Tomcat节点和session信息,说明session绑定成功;

实现session保持

Tomcat支持Session集群,可在各Tomcat服务器间复制全部session信息,当后端一台Tomcat服务器宕机后,Haproxy重新调度用户请求后,在其它正常的Tomcat服务上依然存在用户原先的session信息;

Session集群可在Tomcat服务器规模(一般10台以下)不大时使用,否则会导致复制代价过高;

配置实现

66

67

68

69

70

71

72

73

74

75

76

77

78

79

<code># vi /usr/local/tomcat/conf/server.xml # 完整配置</code>

<code>    </code><code>&lt;Connector port=</code><code>"9000"</code> <code>protocol=</code><code>"HTTP/1.1"</code>

<code>    </code><code>&lt;Engine name=</code><code>"Catalina"</code> <code>defaultHost=</code><code>"localhost"</code> <code>jvmRoute=</code><code>"tomcat1"</code><code>&gt;</code><code># 在Tomcat2主机上替换为tomcat2</code>

<code>&lt;Cluster className=</code><code>"org.apache.catalina.ha.tcp.SimpleTcpCluster"</code>    <code># 添加集群相关配置;</code>

<code>                 </code><code>channelSendOptions=</code><code>"8"</code><code>&gt;</code>

<code>          </code><code>&lt;Manager className=</code><code>"org.apache.catalina.ha.session.DeltaManager"</code> <code># 集群会话管理器选择DeltaManager;</code>

<code>                   </code><code>expireSessionsOnShutdown=</code><code>"false"</code>

<code>                   </code><code>notifyListenersOnReplication=</code><code>"true"</code><code>/&gt;</code>

<code>          </code><code>&lt;Channel className=</code><code>"org.apache.catalina.tribes.group.GroupChannel"</code><code>&gt; </code><code># 为集群中的几点定义通信信道;</code>

<code>            </code><code>&lt;Membership className=</code><code>"org.apache.catalina.tribes.membership.McastService"</code> <code># 定义使用McastService确定集群中的成员</code>

<code>                        </code><code>address=</code><code>"228.25.25.4"</code>    <code># 集群内session复制所用的多播地址</code>

<code>                        </code><code>port=</code><code>"45564"</code>

<code>                        </code><code>frequency=</code><code>"500"</code>

<code>                        </code><code>dropTime=</code><code>"3000"</code><code>/&gt;</code>

<code>            </code><code>&lt;Receiver className=</code><code>"org.apache.catalina.tribes.transport.nio.NioReceiver"</code> <code># 定义以NioReceiver方式接收其它节点的数据;</code>

<code>                      </code><code>address=</code><code>"192.168.0.25"</code><code># 在Tomcat2主机上替换为192.168.0.35</code>

<code>                      </code><code>port=</code><code>"4000"</code>

<code>                      </code><code>autoBind=</code><code>"100"</code>

<code>                      </code><code>selectorTimeout=</code><code>"5000"</code>

<code>                      </code><code>maxThreads=</code><code>"6"</code><code>/&gt;</code>

<code>            </code><code>&lt;Sender className=</code><code>"org.apache.catalina.tribes.transport.ReplicationTransmitter"</code><code>&gt; </code><code># 定义数据复制的发送器;</code>

<code>              </code><code>&lt;Transport className=</code><code>"org.apache.catalina.tribes.transport.nio.PooledParallelSender"</code><code>/&gt;</code>

<code>            </code><code>&lt;</code><code>/Sender</code><code>&gt;</code>

<code>            </code><code>&lt;Interceptor className=</code><code>"org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"</code><code>/&gt;</code>

<code>            </code><code>&lt;Interceptor className=</code><code>"org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"</code><code>/&gt;</code>

<code>          </code><code>&lt;</code><code>/Channel</code><code>&gt;</code>

<code>          </code><code>&lt;Valve className=</code><code>"org.apache.catalina.ha.tcp.ReplicationValve"</code>

<code>                 </code><code>filter=</code><code>""</code><code>/&gt;</code>

<code>          </code><code>&lt;Valve className=</code><code>"org.apache.catalina.ha.session.JvmRouteBinderValve"</code><code>/&gt;</code>

<code>          </code><code>&lt;Deployer className=</code><code>"org.apache.catalina.ha.deploy.FarmWarDeployer"</code>

<code>                    </code><code>tempDir=</code><code>"/tmp/war-temp/"</code>

<code>                    </code><code>deployDir=</code><code>"/tmp/war-deploy/"</code>

<code>                    </code><code>watchDir=</code><code>"/tmp/war-listen/"</code>

<code>                    </code><code>watchEnabled=</code><code>"false"</code><code>/&gt;</code>

<code>          </code><code>&lt;ClusterListener className=</code><code>"org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"</code><code>/&gt;</code>

<code>          </code><code>&lt;ClusterListener className=</code><code>"org.apache.catalina.ha.session.ClusterSessionListener"</code><code>/&gt;</code>

<code>        </code><code>&lt;</code><code>/Cluster</code><code>&gt;</code>

<code>      </code><code>&lt;Host name=</code><code>"xxrenzhe.lnmmp.com"</code>  <code>appBase=</code><code>"webapps"</code>

<code>            </code><code>&lt;Context path=</code><code>""</code> <code>docBase=</code><code>"lnmmpapp"</code> <code>/&gt;</code>

<code># cd /usr/local/tomcat/webapps/lnmmpapp/WEB-INF/</code>

<code># cp /usr/local/tomcat/conf/web.xml .</code>

<code># vi web.xml # 添加如下一行,无需放置于任何容器中</code>

<code>&lt;distributable\&gt;</code>

查看日志

<code># tailf /usr/local/tomcat/logs/catalina.out</code>

<code>May 08, 2014 11:08:13 PM org.apache.catalina.ha.tcp.SimpleTcpCluster memberAdded</code>

<code>INFO: Replication member added:org.apache.catalina.tribes.membership.MemberImpl[tcp:</code><code>//</code><code>{192, 168, 0, 35}:4000,{192, 168, 0, 35},4000, alive=1029, securePort=-1, UDP Port=-1, </code><code>id</code><code>={106 35 -62 -54 -28 61 74 -98 -86 -11 -69 104 28 -114 32 -69 }, payload={}, </code><code>command</code><code>={}, domain={}, ]</code>

<code># 查看到如上信息,则说明session集群已生效,tomcat1已检测到tomcat2节点的存在</code>

第一次访问

<a href="http://s3.51cto.com/wyfs02/M02/26/92/wKioL1NrraHj1dGrAAKnUnDbem8056.jpg" target="_blank"></a>

然后停止tomcat1的nginx服务(service nginx stop),再次访问

<a href="http://s3.51cto.com/wyfs02/M01/26/92/wKiom1NrriChIXusAALXeQXr7wo656.jpg" target="_blank"></a>

说明:虽然因为tomcat1故障,导致用户请求被调度到了tomcat2节点上,但Session ID并未发生改变,即session集群内的所有节点都保存有全局的session信息,很好的实现了用户访问的不中断;,

本文转自 xxrenzhe11 51CTO博客,原文链接:http://blog.51cto.com/xxrenzhe/1408680,如需转载请自行联系原作者