tomcat是Apache软件基金会的Jakarta项目中的核心项目,最新的Servlet和JSP规范可以在Tomcat中很好的表现。做为一个免费的开放源代码的Web应用服务器,属于轻量级的应用服务器,在中小型系统和并发量不是很大的场景下被普遍使用,是开发和调试JSP代码的首选。实际上而言,tomcat是Apache服务器的拓展,可是能够独立运行,tomcat能够独立的去处理html和jsp页面。
css
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它经过在内存中缓存数据和对象来减小读取数据库的次数,从而提升动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,可是客户端能够用任何语言来编写,并经过memcached协议与守护进程通讯。这里主要是作为tomcat的session存储设备。
html
在计算机中,尤为是在网络应用中,称为“会话控制”。Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web 页时,若是该用户尚未会话,则 Web 服务器将自动建立一个 Session 对象。当会话过时或被放弃后,服务器将终止该会话。前端
在现今的互联网架构中会话保持愈来愈重要,可是会话的保持却在必定程度上依赖于提供服务的服务器上,随着并发量的不断提高,服务器最终会因为负载太高而宕机,所以引入了负载均衡机制,可是负载均衡的调度会使得同一用户的请求被调度到不一样的主机之上,会严重的影响到session的保存。
java
这里打算实现两种session会话的保持方案。
一.Tomcat自身的session复制集群方案;
二.Tomcat+memcached的共享session保持方案。
linux
ip地址 | 操做系统 | |
---|---|---|
nginx代理 | 192.168.99.131 | CentOS7.4 |
tomcat1 | 192.168.99.130 | CentOS7.4 |
tomcat2 | 192.168.99.240 | CentOS7.4 |
环境配置:
清空防火墙规则,关闭selinux,安装jdknginx
#清空防火墙规则 iptables -F iptables -X #临时设置关闭selinux setenforce 0 #安装jdk,centos7的源默认最高支持jdk1.8 yum install java-1.8.0-openjdk-devel -y
在<engine>或者<host>配置启用集群,使用Delta Manager to replicate session deltas 启用全部的会话复制。经过all-to-all,意味着会话会被复制到进群中的其余全部节点,这样是设计适用于较小的集群,可是,并不建议在较大的集群上去部署,在使用delta管理器的时候,它将会复制到全部的节点上,甚至是尚未部署应用程序的节点。官方默认提供了一个backupManager的管理器,这个管理器的做用是仅仅将会话数据复制到一个备份节点上,并且,仅仅复制到已经部署了应用的节点,可是这个管理器目前仍在测试阶段,不能保证其正常运行。
web
1.安装nginx并设置代理数据库
#安装nginx,nginx在epel源,所以未安装epel源的话要先安装epel源 yum instll nginx -y
2.修改默认的nginx配置文件apache
vim /etc/nginx/nginx.conf
3.编辑代理配置文件vim
vim /etc/nginx/conf.d/proxy.conf upstream web { server 192.168.99.130:80; server 192.168.99.240:80; } server { listen 80 default_server; index index.jsp index.html; server_name douma.com; location / { proxy_pass http://web; } }
4.检查语法并启动nginx
#检查语法 nginx -t #检查无误后启动nginx systemctl start nginx
1.安装tomcat以及对应的其余管理工具
yum install tomcat tomcat-lib tomcat-admin-webapps tomcat-webapps tomcat-docs-webapp -y
2.配置tomcat显示session会话信息
mkdir -pv /appdata/webapps/ROOT/{lib,classes,WEB-INF} #编写session会话显示页 vim /appdata/webapps/ROOT/index.jsp <%@ page language="java" %> <html> <head><title>TomcatA</title></head> <body> <h1><font color="red">TomcatA</font></h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("magedu.com","magedu.com"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html> #复制全局web.xml到对应目录并修改 cp /etc/tomcat/web.xml /appdata/webapps/ROOT/WEB-INF/ #编辑web.xml 添加<distributable/>字段
3.修改server.xml配置文件
vim /etc/tomcat/server.xml <Host name="douma.com" appBase="/appdata/webapps" unpackWARs="ture" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="douma.com_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8"> <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/> <Channel className="org.apache.catalina.tribes.group.GroupChannel"> <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.0.4" port="45564" frequency="500" dropTime="3000"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="192.168.99.130" #这里改成本机地址 port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6"/> <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> </Sender> <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/> </Channel> <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/> <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/> <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/> <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster> </Host>
4.启动tomcat并访问8080端口
systemctl start tomcat
5.安装nginx
yum install nginx -y
6.编写反代配置
#编辑默认配置文件取消default_server
#添加反代配置 vim /etc/nginx/conf.d/proxy.conf upstream web { server 192.168.99.130:8080; } server { listen 80 default_server; server_name douma.com; location / { index index.jsp index.html; proxy_pass http://web; } }
7.启动nginx
systemctl start nginx
基本配置和tomcat1相同,仅仅须要在编写页面,配置nginx代理配置和配置集群服务时候修改ip地址。
vim /appdata/webapps/ROOT/index.jsp <%@ page language="java" %> <html> <head><title>TomcatB</title></head> <body> <h1><font color="blue">TomcatB</font></h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("magedu.com","magedu.com"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html>
验证
访问前端nginx调度器
刷新一下
虽然刷新了页面,也同时由另外一台服务器响应,可是session会话信息仍是很好的保存下来了。
#classname配置tomcat集群在进行信息传递时互相使用什么类来进行传递;channelsendoptions能够设置为2,4,8.10; #2表示确认发送 Channel.SEND_OPTIONS_USE_ACK #4表示同步发送Channel.SEND_OPTIONS_SYNCHRONIZED_ACK #8表示你异步发送Channel.SEND_OPTIONS_ASYNCHRONOUS #10表示 在异步模式下,能够经过加上确认发送(Acknowledge)来提升可靠性 <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8"> #manager决定如何管理集群的session信息, #className-指定实现org.apache.catalina.ha.ClusterManager接口的类,信息之间的管理. #expireSessionsOnShutdown-设置为true时,一个节点关闭,将致使集群下的全部Session失效 #notifyListenersOnReplication-集群下节点间的Session复制、删除操做,是否通知session listeners #maxInactiveInterval-集群下Session的有效时间(单位:s)。 #maxInactiveInterval内未活动的Session,将被Tomcat回收。默认值为1800s <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/> #Channel是Tomcat节点之间进行通信的工具。 #Channel包括5个组件:Membership、Receiver、Sender、Transport、Interceptor <Channel className="org.apache.catalina.tribes.group.GroupChannel"> #Membership维护集群的可用节点列表。它能够检查到新增的节点,也能够检查到没有心跳的节点 #className-指定Membership使用的类 #address-组播地址 #port-组播端口 #frequency-发送心跳(向组播地址发送UDP数据包)的时间间隔(单位:ms)。默认值为500 #dropTime-Membership在dropTime(单位:ms)内未收到某一节点的心跳,则将该节点从可用节点列表删除。默认值为3000 <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.0.4" port="45564" frequency="500" dropTime="3000"/> #Receiver : 接收器,负责接收消息BioReceiver(阻塞式)、NioReceiver(非阻塞式) #className-指定Receiver使用的类 #address-接收消息的地址(默认是自动,可是最好手动更改成本地网卡对外ip) #port-接收消息的端口 #autoBind-端口的变化区间 #若是port为4000,autoBind为100,接收器将在4000-4099间取一个端口,进行监听 #selectorTimeout-NioReceiver内轮询的超时时间 #maxThreads-线程池的最大线程数 <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="192.168.99.240" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6"/> #sender:发送器负责发送消息 sender内嵌了transport组件,transport组件是负责真正传送消息 <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> #Transport分为两种:bio.PooledMultiSender(阻塞式)、nio.PooledParallelSender(非阻塞式) <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> </Sender> #MessageDispatch15Interceptor-查看Cluster组件发送消息的方式是否设置为Channel.SEND_OPTIONS_ASYNCHRONOUS(Cluster标签下的channelSendOptions为8时)。 #当设置为Channel.SEND_OPTIONS_ASYNCHRONOUS时,MessageDispatch15Interceptor先将等待发送的消息进行排队,而后将排好队的消息转给Sender <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/> </Channel> #Valve :能够做为过滤器,ReplicationValve-在处理请求先后打日志;过滤不涉及Session变化的请求。 #vmRouteBinderValve-Apache的mod_jk发生错误时,保证同一客户端的请求发送到集群的同一个节点 <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/> <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/> #Deployer:同步集群下的全部节点的一致性 <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/> #ClusterListener : 监听器,监听Cluster组件接收的消息,使用DeltaManager时,Cluster接收的信息经过ClusterSessionListener传递给DeltaManager <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster>
图中的memcached在两个tomcat节点都会安装,来实现冗余。图中独立摘出来仅仅是为了方便理解。
1.安装nginx并设置代理
#安装nginx,nginx在epel源,所以未安装epel源的话要先安装epel源 yum instll nginx -y
2.修改默认的nginx配置文件
vim /etc/nginx/nginx.conf
3.编辑代理配置文件
vim /etc/nginx/conf.d/proxy.conf upstream web { server 192.168.99.130:80; server 192.168.99.240:80; } server { listen 80 default_server; index index.jsp index.html; server_name douma.com; location / { proxy_pass http://web; } }
4.检查语法并启动nginx
#检查语法 nginx -t #检查无误后启动nginx systemctl start nginx
1.安装nginx配置本地代理
yum install nginx -y #编辑默认配置文件取消default_server vim /etc/nginx/nginx.conf #建立新的代理配置文件 vim /etc/nginx/conf.d/proxy.conf upstream web { server 192.168.99.130:8080; } server { listen 80 default_server; server_name douma.com; location / { index index.jsp index.html; proxy_pass http://web; } } #语法检查无误后启动nginx nginx -t systemctl start nginx
2.安装tomcat和其余管理工具
yum install tomcat tomcat-lib tomcat-admin-webapps tomcat-webapps tomcat-docs-webapp -y
3.建立测试项目
mkdir -pv /appdata/webapps/ROOT/{lib,classes,WEB-INF} #建立测试页面 vim /appdata/webapps/ROOT/index.jsp <%@ page language="java" %> <html> <head><title>TomcatA</title></head> <body> <h1><font color="red">TomcatA</font></h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("magedu.com","magedu.com"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html> #拷贝默认web.xml文件到新建目录 cp /etc/tomcat/web.xml /appdata/webapps/ROOT/WEB-INF/ #修改web.xml文件添加<distributable/>字段
4.配置memcached的session会话保持
#安装软件包 yum install memcached -y #下载msm的对应jar包
将下载的包放置到/usr/share/java/tomcat下
5.修改server.xml文件
vim /etc/tomcat/server.xml #配置虚拟主机 <Host name="douma.com" appBase="/appdata/webapps" unpackWARs="ture" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="douma.com_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> #在host字段内添加 <Context path="/" docBase="ROOT" reloadable=""> <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" #memcached的节点名(节点名本身定义,仅仅是显示)和对应ip端口 memcachedNodes="n1:192.168.99.130:11211,n2:192.168.99.240:11211" #备用节点设置 failoverNodes="n1" requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" /> </Context>
6.启动tomcat
systemctl start tomcat
7.验证
配置基本同配置tomcat1,要注意修改nginx代理后端的ip
nginx proxy.conf upstream web { server 192.168.99.240:8080; } server { listen 80 default_server; server_name douma.com; location / { index index.jsp index.html; proxy_pass http://web; } } server.xml <Host name="douma.com" appBase="/appdata/webapps" unpackWARs="ture" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="douma.com_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> <Context path="/" docBase="ROOT" reloadalbe=""> <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="n1:192.168.99.130:11211,n2:192.168.99.240:11211" failoverNodes="n1" requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" /> </Context> </Host>
访问代理服务器192.168.99.131