Tomcat(三) Tomcat安装配置:
Tomcat+Nginx+keepalived 实现动静分离、Session会话保持的高可用集群
《Tomcat(一) Tomcat是什么》 以及 《Tomcat(二) Tomcat实现》中,了解到了Tomcat的配置及技术实现,而在《nginx+keepalived 实现主备+双主热备模型的高可用负载均衡代理服务》等Nginx系列文章中了解到了Nginx的配置。
下面将在这些的基础上,先安装Tomcat,再进行配置Tomcat+Nginx+keepalived 的动静分离的高可用集群,最后再配置Tomcat集群,实现Session会话保持。
1、配置环境准备
1-1、模拟环境
1、各服务器主机系统:CentOS 6.4 x86_64
2、反向代理服务器:
node1: IP:192.168.18.241 (host name:node1.tjiyu.com);
node2: IP:192.168.18.242 (host name:node2.tjiyu.com);
VIP1:192.168.18.240;
VIP2:192.168.18.250;
service:nginx 1.10.2 提供反向代理、负载均衡服务;
keepalived 为nginx(VIP)提供高可用服务;
3、后端三台realserver:
realserver1:
IP:192.168.18.251 (host name:realserver1.tjiyu,com);
Service:nginx 1.10.2 提供静态内容WEB服务
realserver2:
IP:192.168.18.252 (host name:realserver2.tjiyu.com);
Service:tomcat 8.5.9 处理动态请求
realserver3:
IP:192.168.18.252 (host name:realserver3.tjiyu.com);
Service:tomcat 8.5.9 处理动态请求
1-2、配置前所需要的准备
各主机需要做以下准备:
1、配置IP、关闭防火墙/SELINUX;
2、时间同步;
3、配置节点名称(不是必须的,最好配置上,方便操作)
在前面《heartbeat v2 haresource 配置可用集群》说到的高可用集群已有详细介绍,这里就不再给出了。
2、nginx和keepalived相关配置说明
关于nginx和keepalived的相关配置可以参考前面的一些文章,如:
Keepalived:《keepalived 及 keepalived配置LVS高可用集群》;
Nginx:《nginx详解》、《nginx编译安装 及 配置WEB服务》、《nginx配置:反向代理 负载均衡 后端健康检查 缓存》;
下面主要是以《nginx+keepalived 实现主备+双主热备模型的高可用负载均衡代理服务》这篇文章配置的nginx+keepalived双主模型反向代理两台nginx Web服务器的高可用集群为基础,把realserver2改为tomcat服务动态请求,以及增加一台realserver3的tomcat,所以keepalived的配置是不变的,需要改动的是nginx中的一些配置。
3、下载安装JDK以及Tomcat
3-1、下载安装JDK
前面文章曾介绍过Tomcat本质上是一个Java语言编写的程序,需要Java类库及运行环境,即需要先安装JDK;先看Tomcat版本可以使用JDK版本范围是多少,再到Orcale官网上选择适合的版本下载,这里使用tomcat-8.5.9版本,可以使用最新的jdk-8u112版本,最终下载的是jdk-8u112-linux-x64.rpm,官网下载地址如下:http://www.oracle.com/technetwork/java/javase/downloads/index.htm
下载后放到realserver2(realserver3同理),开始安装,默认安装到/usr/java目录下,过程如下:
[root@realserver2 soft]# ls[root@realserver2 soft]# rpm -ih jdk-8u112-linux-x64.rpm [root@realserver2 soft]# cd /usr/java/ [root@realserver2 java]# ll
配置环境变量"JAVA_HOME",如下:
[root@realserver2 java]# vim /etc/profile.d/java.sh[root@realserver2 java]# cat /etc/profile.d/java.sh
export JAVA_HOME=/usr/java/latest
export PATH=$JAVA_HOME/bin:$PATH
[root@realserver2 java]# . /etc/profile.d/java.sh
测试查看JDK以主Java虚拟机的版本,一切正常,如下:
[root@realserver2 java]# java -version
3-2、下载安装Tomcat
可以到官网上选择需要的版本下载,这里使用tomcat-8.5.9版本,下载地址如下:http://tomcat.apache.org/download-80.cgi
下载后放到主机上,开始安装:先解压到"/usr/local"目录下,然后为解压后的Tomcat目录创建一个简单的连接,如下:
[root@realserver2 soft]# ll apache-tomcat-8.5.9.tar.gz[root@realserver2 soft]# tar -xf apache-tomcat-8.5.9.tar.gz -C /usr/local/
[root@realserver2 soft]# cd /usr/local/
[root@realserver2 local]# ln -sv apache-tomcat-8.5.9 tomcat
配置环境变量"CATALINA_HOME",如下:
[root@realserver2 local]# vim /etc/profile.d/tomcat.sh[root@realserver2 local]# cat /etc/profile.d/tomcat.sh
export CATALINA_HOME=/usr/local/tomcat
export PATH=$CATALINA_HOME/bin:$PATH
[root@realserver2 local]# . /etc/profile.d/tomcat.sh
查看版本,启动测试,可以看到Tomcat启动后监听了三个端口,其中"8080"是HTTP请求端口,如下:
[root@realserver2 local]# catalina.sh version[root@realserver2 local]# catalina.sh start
[root@realserver2 local]# netstat -tunlp | grep java
在client端浏览器访问安装的Tomcat:http://192.168.18.252:8080,可以看到Tomcat自身提供的信息及管理页面,如下:
在Tomcat提供的"catalina.sh"脚本基础上,为Tomcat提供SysV脚本,方便使用、管理,如下:
[root@realserver2 ~]# vim /etc/rc.d/init.d/tomcat[root@realserver2 ~]# cat /etc/rc.d/init.d/tomcat
#!/bin/sh
# Tomcat init script for Linux.
#
# chkconfig: 2345 96 14
# description: The Apache Tomcat servlet/JSP container.
JAVA_HOME=/usr/java/latest
CATALINA_HOME=/usr/local/tomcat
export JAVA_HOME CATALINA_HOME
#exec $CATALINA_HOME/bin/catalina.sh $*
start() {
$CATALINA_HOME/bin/catalina.sh configtest &> /dev/null
if [ $? -ne 0 ];then
echo "Error in configuration file,check with tomcat configuration file."
exit 5
fi
if pidof java &> /dev/null;then
echo "Tomcat is running...."
exit 4
else
exec $CATALINA_HOME/bin/catalina.sh start
fi
}
stop() {
pidof java &> /dev/null
if [ $? -ne 0 ];then
echo "Tomcat is stoped..."
else
$CATALINA_HOME/bin/catalina.sh stop
fi
}
configtest() {
pidof java &> /dev/null
if [ $? -eq 0 ];then
echo "Tomcat is running,please stop the test."
exit 3
else
exec $CATALINA_HOME/bin/catalina.sh configtest
fi
}
version() {
exec $CATALINA_HOME/bin/catalina.sh version
}
case $1 in
start)
start ;;
stop)
stop ;;
restart)
stop
sleep 1
start ;;
configtest)
configtest ;;
version)
version ;;
*)
echo "Usage: `basename $0` {start|stop|restart|configtest|version}"
exit 1 ;;
esac
[root@realserver2 ~]# chmod +x /etc/rc.d/init.d/tomcat
[root@realserver2 ~]# chkconfig --add tomcat
[root@realserver2 ~]# chkconfig tomcat --list
[root@realserver2 ~]# service tomcat version
同理在realserver3上也安装Tomcat。
4、配置Nginx反向代理请求实现动静分离
配置两台反向代理服务器node1和node2上的Nginx配置文件"/etc/nginx/nginx.conf",配置过程如下:
[root@node1 ~]# vim /etc/nginx/nginx.conf[root@node1 ~]# service nginx reload [root@node1 ~]# scp /etc/nginx/nginx.conf root@node2:/etc/nginx/
配置文件内容如下:
#user nobody;worker_processes 2;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
upstream appserver { #定义名为webserver的负载均衡组,在下面proxy_pass引用
#ip_hash; #ip_hash负载均衡策略,注意,当下面定义代理服务器为backu时,当后端服务器重新上线时,不能进行正常转发
least_conn; #最少连接负载均衡策略
#least_time last_byte; #最少响应时间策略,商业版本
server 192.168.18.252:8080 weight=1 max_fails=2 fail_timeout=2; #realserver1 权重2/两次检测失败,不向其转发/检查超时两秒为失败
server 192.168.18.253:8080 weight=1 max_fails=2 fail_timeout=2; #realserver2
server 127.0.0.1:8080 weight=1 backup; #指定代理服务器自身作为备份server,当所有后端服务器都宕机时,对外提供维护提示页面
}
#定义一个完整的缓存空间; 缓存数据存储在/data/nginx/cache目录中/配置在该目录下再分两层目录/键(元数据)存放的内存空间,名称为one(proxy_cache引用),10m内存空间大小/最大缓存数据磁盘空间的大小/10m未被访问的缓存数据将从缓存中删除
#proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m max_size=1G inactive=10m;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
#add_header X-Cache "$upstream_cache_status form $server_addr"; #给请求响应增加一个头部信息,表示从服务器上返回的cache状态怎么样(有没有命中)
#除去下面的静态内容,默认都为动态请求
location / {
proxy_pass http://appserver; #引用上面定义的tomcat负载均衡组
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#$remote_addr; #代理转发的请求头部增加"X-Forwarded-For"客户端地址
}
#页面静态内容
location ~ .*\.(html|js|css)$ {
proxy_pass http://192.168.18.251; #代理到192.168.18.251
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#$remote_addr; #代理转发的请求头部增加"X-Forwarded-For"客户端地址
expires 12h;
# proxy_cache one; #引用上面定义上的缓存空间,同一缓存空间可以在几个地方使用
#proxy_cache_valid 200 302 10m;
#proxy_cache_valid 404 1m; #对代码200和302的响应设置10分钟的缓存,对代码404的响应设置为1分钟:
}
#图片静态内容
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
proxy_pass http://192.168.18.251; #代理到192.168.18.251
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#$remote_addr; #代理转发的请求头部增加"X-Forwarded-For"客户端地址
expires 30d;
}
}
server { #定义虚拟主机,当所有后端服务器都宕机时,使得代理服务器自身可以对外提供维护提示页面
listen 8080;
server_name localhost;
root /data/web/errorpage;
index index.html;
}
}
另外,可以为静态内容配置缓存,当然缓存量比较大还可以加一台varnish缓存服务器,这里就不再多介绍了。
5、部署测试
5-1、部署测试程序
为测试配置效果,我们准备了一个Java Web测试程序,为realserver2/3两台Tomcat应用服务器都部署这个Java Web程序,程序URI为"/api/test",返回服务器名称和Session ID,其中并没有HTML页面文件等静态内容,如下:
@WebServlet("/test") public class TestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String host = request.getLocalName();
String sessionId = request.getSession().getId();
response.getWriter().print("{host:"+host +
",sessionId:" + sessionId +"}");
}
}
而我们的静态文件,如html/js/图片,就放到realserver1的Nginx WEB服务器中,这个页面中主要是通过AJAX来请求上面Tomcat部署的Java WEB应用,把返回结果显示在页面上,如下:
[root@realserver1 web]# lsjquery-1.9.1.min.js page.html test.js tomcat.png
[root@realserver1 web]# cat page.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>tomcat+nginx测试</title>
</head>
<script src="jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="test.js"></script>
<body>
<img src="tomcat.png" />
<div >
<input type="button" value="动态请求:/api/test" onClick="requestApi()"/>
</div>
<p>请求结果:</p>
<ol>
</ol>
</body>
</html>
[root@realserver1 web]# cat test.js
var g_Url = "/api/test";
function requestApi() {
$.get(g_Url,function(data,status){
$("ol").append(data );
});
[root@realserver1 web]#
部署完成后,通过Client端浏览器分别访问测试,一切正常,如下:
5-2、测试Nginx反向代理的动静分离
我们通过VIP访问page.html页面:http://192.168.18.240/page.html,这时node节点的Nginx反向代理到realserver1的Nginx WEB服务器,返回部署的页面及图片等;然后点击页面上的动态请求按键,发出动态请求:http://192.168.18.240/api/test,可以看到代理到了realserver2/3两台Tomcat应用服务器中,并返回结果,如下:
6、配置Tomcat session会话集群
从上面测试结果可以看到,每次请求Tomcat返回的Session ID都不一样,即无法保持会话,前面文章也介绍过了,Tomcat是可以通过自身的Cluster等组件来配置成集群,并且有几种Tomcat Session Manager组件可以使集群会话得以保持,还可以用Mencache缓存服务器来保存Tomcat Session。
下面使用DeltaManager的会话管理组件来配置,在realserver2/3两台Tomcat的配置文件server.xml的Engine组件标签中分别添加相同的内容,如下:
<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="auto"
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.MessageDispatchInterceptor"/>
</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.ClusterSessionListener"/>
</Cluster>
然后再部署的Java WEB应用程序的web.xml中添加"<distributable/>"标签,如下:
重启两台Tomcat后,再次测试,可以看到不同客户端的访问,有不同Session ID,但同一客户端的Session ID都保持一样,如下:
到这里,我们完成了安装Tomcat,配置tomcat+nginx+keepalived 的动静分离的高可用集群、配置Tomcat集群实现Session会话保持……
【参考资料】
1、nginx官网文档:http://nginx.org/en/docs/
2、Apache Tomcat User Guide:http://tomcat.apache.org/tomcat-8.5-doc/index.html
3、Apache Tomcat 8 Configuration Reference:ttp://tomcat.apache.org/tomcat-8.5-doc/config/index.html
4、nginx+keepalived 实现主备+双主热备模型的高可用负载均衡代理服务