tomcat集群部署的三种方式
通常配置tomcat集群有三种方式:使用DNS轮询,使用apache r-proxy代理方式,使用apache mod_jk方式。
(1)DNS轮询的缺点:当集群中某台服务器停止之后,用户由于dns缓存的缘故,便无法访问服务,必 须等到dns解析更新,或者这台服务器重新启动。还有就是必须把集群中的所有服务端口暴露给外界,没有用apache做前置代理的方式安全,并 且占用大量公网IP地址,而且tomcat还要负责处理静态网页资源,影响效率。优点是集群配置最简单,dns设置也非常简单。
(2)R- proxy的缺点:当其中一台tomcat停止运行的时候,apache仍然会转发请求过去,导致502网关错误。但是只要服务器再启动就不存 在这个问题。
(3)mod_jk方式的优点是,Apache 会自动检测到停止掉的tomcat,然后不再发请求过去。缺点就是,当停 止掉的tomcat服务器再次启动的时候,Apache检测不到,仍然不会转发请求过去。
R-proxy和mod_jk的共同优点是.可 以只将Apache置于公网,节省公网IP地址资源。可以通过设置来实现Apache专门负责处理静态网页,让Tomcat专门负责处理jsp和 servlet等动态请求。共同缺点是:如果前置Apache代理服务器停止运行,所有集群服务将无法对外提供。R-proxy和 mod_jk对静态页面请求的处理,都可以通设置来选取一个尽可能优化的效果。这三种方式对实现最佳负载均衡都有一定不足,mod_jk相对好些,可以通过设置lbfactor参数来分配请求任务。
安装tomcat
略
配置第二台tomcat
拷贝第一台tomcat目录和jdk目录到第二台服务器
# rsync -ar 10.0.0.20:/home/test/softwares/jdk* ./ # rsync -ar 10.0.0.20:/home/test/softwares/apache-tomcat-8.5.6 ./
两台服务器修改server.xml
<Engine name="Catalina" defaultHost="apache.a.com"> <Host name="apache.tom.com" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Context docbase="app" path="/app" reloadable="true" />
<Engine name="Catalina" defaultHost="tomcat.a.com"> <Host name="apache.tom.com" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Context docbase="app" path="/app" reloadable="true" />
使用apache的mod_jk模块实现负载均衡(好像只能是本地连接使用,跨主机我没配置成功)
mod_jk模块安装过程
# cd /opt/softwares/http-2.4.48/modules # wget http://archive.apache.org/dist/tomcat/tomcat-connectors/jk/binaries/linux/jk-1.2.31/x86_64/mod_jk-1.2.31-httpd-2.2.x.so # mv mod_jk-1.2.31-httpd-2.2.x.so mod_jk.so
修改apache主配置httpd.conf文件,添加
# vim ../conf/httpd.conf
Include conf/mod_jk.conf
配置 mod_jk.conf 和 workers.properties
# vim conf/mod_jk.conf
添加如下内容: # mod_jk配置mod_jk包 LoadModule jk_module modules/mod_jk.so # workers 配置工作负责文件 JkWorkersFile conf/workers.properties # jk_log 配置jk日志文件 JkLogFile logs/mod_jk.log # jk log leve 配置日志级别 JkLogLevel info # 配置jk日志内存共享 JkShmFile logs/mod_jk.shm # balancer 配置负载均衡模式 JkMount /*.jsp balancer JkLogStampFormat "[%a %b %d %H:%M:%S %Y] " JkRequestLogFormat "%w %V %T" # JkMount /servlet/* ajp13 #此处的ajp13是workers.properties文件中的worker.list配置的值,一定要写的一样,否则会报错 #JkMount /*.jsp ajp13 #JkMount /*.do ajp13 JkAutoAlias /opt/softwares/http-2.4.48/htdocs
配置workers.properties
# vim conf/workers.properties
添加如下内容:
#tomcat1的配置 worker.tomcat1.port=8009 worker.tomcat1.host=10.0.0.10 worker.tomcat1.reference=worker.template worker.tomcat1.activation=A #worker.tomcat1.lbfactor=1 #tomcat2 的配置 worker.tomcat2.port=8009 worker.tomcat2.host=10.0.0.20 worker.tomcat2.reference=worker.template worker.tomcat2.activation=A #worker.tomcat2.lbfactor=1 worker.list=balancer #balancer 负载配置 worker.balancer.type=lb worker.balancer.balance_workers=tomcatA,tomcatB worker.balancer.sticky_session=1 #tempalte 负载模板配置 worker.template.type=ajp13
报错
此部分的md_jk如果和apache版本不兼容,会有如下报错
httpd: Syntax error on line 513 of /opt/softwares/http-2.4.48/conf/httpd.conf: Syntax error on line 2 of /opt/softwares/http-2.4.48/conf/mod_jk.conf: Cannot load modules/mod_jk.so into server: /opt/softwares/http-2.4.48/modules/mod_jk.so: undefined symbol: ap_get_server_version
解决办法(重新编译安装mod_jk)
下载包: 我这里的apache版本是2.4.48的
# wget https://downloads.apache.org/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.48-src.tar.gz
解压并编译安装
# tar xfz tomcat-connectors-1.2.48-src.tar.gz # cd tomcat-connectors-1.2.48-src/native # ./configure --with-apxs=/opt/softwares/http-2.4.48/bin/apxs # make
make编译成功以后,会生成apache-2.0目录,里面有mod_jk.so,将其拷贝到apache的modules目录即可
# cp apache-2.0/mod_jk.so /opt/softwares/http-2.4.48/modules/
<!-- Define an AJP 1.3 Connector on port 8009 --> <Connector port="8009" protocol="AJP/1.3" address="10.0.0.20" redirectPort="8443" secretRequired=""/> [root@apache bin]# vim ../conf/workers.properties #tomcatB的配置 worker.tomcatA.type=ajp13 worker.tomcatA.port=8009 worker.tomcatA.host=10.0.0.20 worker.tomcatA.reference=worker.template worker.tomcatA.activation=A worker.tomcatA.lbfactor=1 #tomcatA 的配置 worker.tomcatB.type=ajp13 worker.tomcatB.port=9009 worker.tomcatB.host=localhost worker.tomcatB.reference=worker.template worker.tomcatB.activation=A worker.tomcatB.lbfactor=1 worker.list=router #balancer 负载配置 worker.router.type=lb worker.router.balance_workers=tomcatA,tomcatB worker.router.sticky_session=1 #tempalte 负载模板配置 worker.template.type=ajp13 ~
集群配置
<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" /> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener" /> </Cluster>
<Manager>用于指定集群会话管理器,默认为DeltaManager