Tomcat:
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响HTML(标准通用标记语言下的一个应用)页面的访问请求。实际上Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。
诀窍是,当配置正确时,Apache 为HTML页面服务,而Tomcat 实际上运行JSP 页面和Servlet。另外,Tomcat和IIS等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的Servlet容器是Tomcat的默认模式。不过,Tomcat处理静态HTML的能力不如Apache服务器。目前Tomcat最新版本为9.0。
实验:Tomcat的会话保持
(1) nginx + tomcat cluster, httpd(proxy_http_module)+tomcat cluster,httpd(proxy_ajp_module)+tomcat cluster;
(2) tomcat cluster升级为session cluster, 使用deltaManager;
(3) tomcat cluster将会话保存至memcached中;
简单拓扑图:
实验环境:
三台centos7
代理服务器:ip:172.16.250.111
TomcatA ip:192.168.18.98
TomcatB ip:192.168.18.99
为实验环境顺利进行,关闭防火墙,与SELinux。
一、Tomcat实现负载均衡,客户端经过代理进入tomcat
1.Nginx作为代理服务器:
1):在TomcatA,B安装Tomcat的实验环境及Tomcat。
[root@cnetos7 ~]#yum -y install java-1.8.0-openjdk-devel tomcat tomcat-admin-webapps tomcat-docs-webapp tomcat-lib tomcat-webapps
//这里yum安装 java-1.8.0-openjdk-devel安装包,能把java-1.8.0-openjdk,java-1.8.0-openjdk-headless主要包,作为依赖装上。
[root@cnetos7 ~]#java -version //显示openjdk的版本
openjdk version "1.8.0_102"
OpenJDK Runtime Environment (build 1.8.0_102-b14)
OpenJDK 64-Bit Server VM (build 25.102-b14, mixed mode)
2):在TomcatA.B上修改配置文件。
[root@cnetos7 ~]#mkdir /usr/share/tomcat/webapps/test/{classes,lib,WEB-INF} -pv //创建相应目录
//JSP WebAPP的组织结构:
//ROOT(/): webapps的根目录
//index.jsp:主页;
//...
//WEB-INF/:当前webapp的私有资源路径;通常用于存储当前webapp的web.xml和context.xml配置文件;
//META-INF/:类似于WEB-INF/;
//classes/:类文件,当前webapp所提供的类;
//lib/:类文件,当前webapp所提供的类,被打包为jar格式
[root@cnetos7 tomcat]#cd /usr/share/tomcat/webapps/test
[root@cnetos7 test]#cat index.jsp //创建一个测试页
<%@ page language="java" %>
<html>
<head><title>TomcatB</title></head>
<body>
<h1><font color="blue">TomcatB.linux.acom</font></h1>
<table align="centre" border="1">
<tr>
<td>Session ID</td>
<% session.setAttribute("linux.com","linux.com"); %>
<td><%= session.getId() %></td>
</tr>
<tr>
<td>Created on</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
</html>
同样的操作在TomcatA上操作一次
[root@cnetos7 ROOT]#systemctl start tomcat //TomcatA.B启动Tomcat
[root@cnetos7 ROOT]#ss -ntl 查看相应端口是否打开 tomcat 端口8080
测试是否正常运行Tomcat
3):设置Nginx代理
安装并测试
[root@centos7 ~]#yum -y install nginx //安装Nginx
[root@centos7 ~]#vim /etc/nginx/nginx.conf //编辑Nginx的配置文件
添加如下信息:
upstream appsrvs { //添加组
server 192.168.18.98:8080;
server 192.168.18.99:8080;
}
[root@centos7 ~]#vim /etc/nginx/conf.d/tomcat.conf //添加一个主机
server {
server_name www.linux.com; //主机名
listen 80; //监听端口
index index.jsp index.html; //默认主页
location / {
proxy_pass http://appsrvs/; //代理
}
}
测试:在Windows上测试时把域名解析成自己的主机现在简单的代理已经完成。
2.HAproxy作为代理
tomcat A,B不需另外设置,只在代理服务器上做修改。
1).停止Nginx服务。
[root@centos7 ~]#systemctl stop nginx
[root@centos7 ~]#ss -ntl
2)安装haproxy
[root@centos7 ~]#yum -y install haproxy
[root@centos7 ~]#vim /etc/haproxy/haproxy.cfg //设置haproxy配置文件
frontend http-in
bind *:80
default_backend appsrvs
backend appsrvs
balance roundrobin
server app1 192.168.18.98:8080 check
server app2 192.168.18.99:8080 check
listen stats
bind *:8008
stats enable
测试;
这里通过ip访问,如需通过域名,需在TomcatA,B的server.xml定义主机及相同的主机名,上面Nginx通过域名访问的是默认配置文件下新建的一个test目录。如下:
[root@centos7 ~]#vim /etc/tomcat/server.xml 添加如下信息
<Host name="www.linux.com" appBase="/data/webapps/"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="linux_access_log." suffix=".log"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
[root@centos7 ~]#mkdir /data/webapps/ROOT -pv
[root@centos7 ~]#cp -r /usr/share/tomcat/webapps/test/* /data/webapps/ROOT
在TomcatA.B相同的操作
3.httpd作为代理
tomcat A,B不需另外设置,只在代理服务器上做修改。
1).停止haproxy服务。
[root@centos7 ~]#systemctl stop haproxy
[root@centos7 ~]#ss -ntl
2)安装httpd
[root@centos7 ~]#yum -y install httpd
[root@centos7 ~]#httpd -M //查看相应模块是否已加载
1.tomcat cluster:http connector //对应相应模块
httpd: proxy_module, proxy_http_module, proxy_balancer_module
2.tomcat cluster:ajp connector /对应相应模块
httpd: proxy_module, proxy_ajp_module, proxy_balancer_module
3)配置httpd
[root@centos7 ~]#vim /etc/httpd/conf.d/tomcat.conf //配置httpd代理服务
<proxy balancer://appsrvs> //定义服务器组
BalancerMember http://192.168.18.98:8080 //BalancerMember相当于Nginx的server
BalancerMember http://192.168.18.99:8080
ProxySet lbmethod=byrequests //调度的方法轮循
</Proxy>
<VirtualHost *:80>
ServerName www.linux.com
ProxyVia On
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / balancer://appsrvs/
ProxyPassReverse / balancer://appsrvs/
<Location />
Require all granted
</Location>
</VirtualHost>
[root@centos7 ~]#systemctl restart httpd
4)测试:
成功代理;
5)会话粘性的实现方法:
[root@centos7 ~]#vim /etc/httpd/conf.d/tomcat.conf //配置httpd代理服务
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<proxy balancer://appsrvs>
BalancerMember http://192.168.18.98:8080 route=TomcatA loadfactor=1
BalancerMember http://192.168.18.99:8080 route=TomcatB loadfactor=1
ProxySet lbmethod=byrequests
ProxySet stickysession=ROUTEID //定义cookie会话信息
</Proxy>
<VirtualHost *:80>
ServerName www.linux.com
ProxyVia On
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / balancer://appsrvs/
ProxyPassReverse / balancer://appsrvs/
<Location />
Require all granted
</Location>
</VirtualHost>
[root@centos7 ~]#systemctl restart httpd
[root@centos7 ~]#ss -ntl
6)测试
7)使用tomcat cluster:ajp connector
只需改动:
[root@centos7 ~]#vim /etc/httpd/conf.d/tomcat.conf
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<proxy balancer://appsrvs>
BalancerMember ajp://192.168.18.98:8009 route=TomcatA loadfactor=1 //ajp
BalancerMember ajp://192.168.18.99:8009 route=TomcatB loadfactor=1
ProxySet lbmethod=byrequests
ProxySet stickysession=ROUTEID
</Proxy>
<VirtualHost *:80>
ServerName www.linux.com
ProxyVia On
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / balancer://appsrvs/
ProxyPassReverse / balancer://appsrvs/
<Location />
Require all granted
</Location>
</VirtualHost>
[root@centos7 ~]#systemctl restart httpd
[root@centos7 ~]#ss -ntl
二、tomcat cluster升级为session cluster, 使用deltaManager;
1.配置TomcatA.B主配置文件:
查看官方文档:http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html
[root@cnetos7 ~]#vim /etc/tomcat/server.xml
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcatB"> //添加名字区分
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Context path="/test" docBase="test" reloadable="true" /> //路径,没有写可能会报错
<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.27.27.4" //多播段可视情况修改
port="45564"
frequency="500"
dropTime="3000"/>
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
address="192.168.18.99" //这里写自己的ip
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下添加上面这段
cp /etc/tomcat/web.xml /usr/share/tomcat/webapps/test/WEB-INF/
//复制web.xml文件 在里面添加<distributable/> 元素
相同的操作在TomcatA上操作一遍
注意:CentOS 7上的tomcat自带的文档中的配置示例有语法错误;
<ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
2)测试:成功实现会话保持不变,即使后端不在同一服务器上。
三、 tomcat cluster将会话保存至memcached中;
memcached : 高性能、分布式的内存对象缓存系统. 无持久存储功能;仅支持存储流式化数据;
准备环境:
memcached与tomcat 存于同一台服务器。
https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration下载相关的jar文件。
下载如下jar文件至各tomcat节点的tomcat安装目录下的lib目录中,其中的${version}要换成你所需要的版本号,tc${6,7,8}要换成与tomcat版本相同的版本号。
memcached-session-manager-${version}.jar
memcached-session-manager-tc${6,7,8}-${version}.jar
spymemcached-${version}.jar
msm-javolution-serializer-${version}.jar
javolution-${version}.jar
1.安装 memcached
[root@cnetos7 ~]#yum -y install memcached
分别在两个tomcat上的某host上定义一个用于测试的context容器,并在其中创建一个会话管理器,如下所示:
[root@cnetos7 ~]#vim /etc/tomcat/server.xml
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tcB">
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Context path="/test" docBase="test" reloadable="true">
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
memcachedNodes="n1:192.168.18.99:11211,n2:192.168.18.100:11211"
failoverNodes="n1"
requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"
/>
</Context>
[root@cnetos7 ~]#systemctl restart tomcat
[root@cnetos7 ~]#systemctl start memcached
[root@cnetos7 ~]#ss -ntl //查看相应的11211端口
测试