标签:selector status options 建议 请求 save 上下 root pes
下面我们来介绍一下tomcat几种实际应用:
(1) LB tomcat nginx tomcats apache tomcats (2) LB tomcat cluster (3) LB tomcat session server memcached
前面我们还了解了会话保持有三种方式:
session sticky session cluster session server
下面我们来分别实现这些应用:
首先,我们准备环境:
192.168.2.50, node4.ckh.com 192.168.2.30, node5.ckh.com 192.168.2.70, node6.ckh.com
一、nginx + tomcat
1、准备环境
1.1 都安装jdk和tomcat并配置环境变量
1.2 tomcat配置
(1)开启日志
# vim /usr/local/tomcat/conf/server.xml
(2)添加host虚拟主机
<Host name="node5.ckh.com" appBase="/data/webapps" autoDeploy="true"> <Context path="" docBase="ROOT" reloadable="true" /> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="/data/logs" prefix="web1_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host>
1.3 创建所需目录
# mkdir -pv /data/webapps/ROOT/{lib,classes,META-INF,WEB-INF} # mkdir /data/logs
1.4 编写测试页面
# vim /data/webapps/ROOT/index.jsp
<%@ page language="java" %> <%@ page import="java.util.*" %> <html> <head> <title> JSP Test Page On node5 </title> </head> <body> <% out.println("hello, node5"); %> </body> </html>
node4上配置只要将node5改成node4,其他配置都不变。
1.3 nginx配置
http上下文中定义backend server:
upstream tcsrvs { server node4.ckh.com:8080; server node5.ckh.com:8080; }
server上下文中定义将动态资源反向代理至后端server:
location ~* \.(jsp|do)$ { proxy_pass http://tcsrvs; }
1.4 测试
浏览器访问: http://192.168.2.70/index.jsp, 默认访问的localhost虚拟主机,所以node4和node5上还需要在server.xml中将默认虚拟主机改为我们定义的虚拟主机名。 再次访问,成功负载均衡。
如果我们期望用户的请求直接到后端某一特定主机,而不要让它负载均衡,用来实现做session sticky的功能。
我们只需要在upstream中添加ip_hash就可以:
upstream tcsrvs { ip_hash; server node4.ckh.com:8080; server node5.ckh.com:8080; }
二、apache + tomcat
apache结合tomcat来实现反向代理、负载均衡这些功能时有三种实现方式:
(1) http协议实现
apache: mod_proxy mod_proxy_http mod_proxy_balancer tomcat http connector (2) ajp协议实现
apache: mod_proxy mod_proxy_ajp mod_proxy_balancer tomcat ajp connector (3) jk模块实现
apache: mod_jk tomcat: ajp connector
第一种方法的实现:
1. node6上httpd配置
1.1 取消中心主机的配置
# vim /etc/httpd/conf/httpd.conf 注释掉DocumentRoot
1.2 定义虚拟主机:
# vim /etc/httpd/conf.d/vhosts.conf
<Proxy balancer://lbcluster1> BalancerMember http://192.168.2.50:8080 loadfactor=10 route=TomcatB BalancerMember http://192.168.2.30:8080 loadfactor=10 route=TomcatA </Proxy> <VirtualHost *:80> ServerName web1.ckh.com ProxyVia On ProxyRequests Off ProxyPreserveHost On <Proxy *> Require all granted </Proxy> ProxyPass / balancer://lbcluster1/ ProxyPassReverse / balancer://lbcluster1/ <Location /> Require all granted </Location> </VirtualHost>
node4 AND node5配置
# vim server.xml
<Engine name="Catalina" defaultHost="node4.ckh.com" jvmRoute="TomcatB"> <Engine name="Catalina" defaultHost="node5.ckh.com" jvmRoute="TomcatA">
编辑tomcat中index.jsp
node4
<%@ page language="java" %> <html> <head> <title>TomcatB</title> </head> <body> <h1><font color="blue">TomcatB.ckh.com</font></h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("ckh.com", "ckh.com"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html>
node5
<%@ page language="java" %> <html> <head> <title>TomcatA</title> </head> <body> <h1><font color="red">TomcatA.ckh.com</font></h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("ckh.com", "ckh.com"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html>
如果要实现会话绑定session sticky:
node6:
# vim /etc/httpd/conf.d/vhosts.conf
添加如下两处内容即可实现会话保持功能
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED //1 <Proxy balancer://lbcluster1> BalancerMember http://192.168.2.50:8080 loadfactor=10 route=TomcatB BalancerMember http://192.168.2.30:8080 loadfactor=10 route=TomcatA ProxySet stickysession=ROUTEID //2 </Proxy> <VirtualHost *:80> ServerName web1.ckh.com ProxyVia On ProxyRequests Off ProxyPreserveHost On <Proxy *> Require all granted </Proxy> ProxyPass / balancer://lbcluster1/ ProxyPassReverse / balancer://lbcluster1/ <Location /> Require all granted </Location> </VirtualHost>
第二种方法的实现:ajp协议的示例
node6:
# vim /etc/httpd/conf.d/vhosts.conf
要想实现会话绑定,只要将1处内容注释去掉即可
<Proxy balancer://lbcluster1> BalancerMember http://192.168.2.50:8080 loadfactor=10 route=TomcatB BalancerMember http://192.168.2.30:8080 loadfactor=10 route=TomcatA #ProxySet stickysession=ROUTEID //1 </Proxy> <VirtualHost *:80> ServerName web1.ckh.com ProxyVia On ProxyRequests Off ProxyPreserveHost On <Proxy *> Require all granted </Proxy> ProxyPass / balancer://lbcluster1/ ProxyPassReverse / balancer://lbcluster1/ <Location /> Require all granted </Location> </VirtualHost>
node4 AND node5
# vim /usr/local/tomcat/conf/server.xml
ajp connector注释要打开,可能1和2这两处内容要修改
<Connector protocol="AJP/1.3" port="8009" address="::" //1 redirectPort="8443" secretRequired="" /> //2
测试反向代理和负载均衡
浏览器访问:http://192.168.2.70/index.jsp
补充:mod_proxy_balancer模块内置的manager:
node6中虚拟主机中定义:
<Location /balancer-manager> SetHandler balancer-manager Proxypass ! Order Deny,Allow Allow from all </Location>
有些httpd版本可能支持下面写法:
<Location /balancer-manager> SetHandler balancer-manager Proxypass ! Require all granted </Location>
第三种方法的实现
下载tomcat-connectors:
http://archive.apache.org/dist/tomcat/tomcat-connectors/jk/tomcat-connectors-1.2.46-src.tar.gz
安装tomcat-connectors
# tar xf tomcat-connectors-1.2.46-src.tar.gz # cd tomcat-connectors-1.2.46-src # cd native # ./configure --help 编译安装tomcat-connectors,所以我们需要安装开发坏境 # yum install httpd-devel gcc glibc-devel -y # yum groupinstall "Development Tools" --setopt=group_package_types=mandatory,default,optional -y # ./configure --with-apxs=/usr/bin/apxs # make && make install
反代示例:
# cd /etc/httpd/conf.d # vim mod_jk.conf
LoadModule jk_module modules/mod_jk.so JKWorkersFile /etc/httpd/conf.d/workers.properties JKLogFile logs/mod_jk.log JKLogLevel debug JKMount /* TomcatA JKMount /status/ stat1
# vim /etc/httpd/conf.d/workers.properties
worker.list=TomcatA,stat1 worker.TomcatA.port=8009 worker.TomcatA.host=192.168.2.30 worker.TomcatA.type=ajp13 worker.TomcatA.lbfactor=1 worker.stat1.type = status
注意:status的访问要做访问控制
负载均衡示例:
# cd /etc/httpd/conf.d # vim mod_jk.conf
LoadModule jk_module modules/mod_jk.so JKWorkersFile /etc/httpd/conf.d/workers.properties JKLogFile logs/mod_jk.log JKLogLevel debug JKMount /* lbcluster1 JKMount /status/ stat1
# vim /etc/httpd/conf.d/workers.properties
worker.list = lbcluster1,stat1 worker.TomcatA.type = ajp13 worker.TomcatA.host = 192.168.2.30 worker.TomcatA.port = 8009 worker.TomcatA.lbfactor = 1 worker.TomcatB.type = ajp13 worker.TomcatB.host = 192.168.2.50 worker.TomcatB.port = 8009 worker.TomcatB.lbfactor = 1 worker.lbcluster1.type = lb worker.lbcluster1.sticky_session = 0 worker.lbcluster1.balance_workers = TomcatA, TomcatB worker.stat1.type = status
要想实现会话绑定,只需要修改worker.properties中这一行:
worker.lbcluster1.sticky_session = 1
mod_jk模块详情可参考下面的文档:
配置apache通过mod_jk模块与Tomcat连接 mod_jk是ASF的一个项目,是一个工作于apache端基于AJP协议与Tomcat通信的连接器,它是apache的一个模块,是AJP协议的客户端(服务端是Tomcat的AJP连接器)。 # tar xf tomcat-connectors-1.2.46-src.tar.gz # cd tomcat-connectors-1.2.37-src/native/ # ./configure --with-apxs=/usr/local/apache/bin/apxs # make && make install apache要使用mod_jk连接器,需要在启动时加载此连接器模块。为了便于管理与mod_jk模块相关的配置,这里使用一个专门的配置文件 /etc/httpd/extra/httpd-jk.conf来保存相关指令及其设置。其内容如下: LoadModule jk_module modules/mod_jk.so JKWorkersFile /etc/httpd/extra/workers.properties JKLogFile logs/mod_jk.log JKLogLevel debug JKMount /* TomcatA JKMount /status/ stat1 除了需要使用LoadModule指令在apache中装载模块外,mod_jk还需要在apache的主配置文件中设置其他一些指令来配置其工作属性。如JKWorkersFile则用于指定保存了worker相关工作属性定义的配置文件,JKLogFile则用于指定mod_jk模块的日志文件,JKLogLevel则可用于指定日志的级别(info,error,debug),此外还可以使用JKRequestLogFormat自定义日志信息格式。而JKMount(格式:JKMount <URL to match> <Tomcat worker name>)指定则用于控制URL与Tomcat workers的对应关系。 为了让apache能使用/etc/httpd/extra/httpd-jk.conf配置文件中的配置信息,需要编辑/etc/httpd/httpd.conf,添加如下一行:Include /etc/httpd/extra/httpd-jk.conf 对于apache代理来说,每一个后端的Tomcat实例中的engine都可以视作一个worker,而每一个worker的地址、连接器的端口等信息都需要在apache端指定以便apache可以识别并使用这些worker。约定俗成,配置这些信息的文件通常为workers.properties,其具体路径则是使用前面介绍过的JKWorkersFile指定的,在apache启动时,mod_jk会扫描此文件获取每一个worker的配置信息。比如,我们这里使用/etc/httpd/extra/workers.properties。 workers.properties文件一般由两类指令组成:一是mod_jk可以连接的各worker名称列表,二是每一个worker的属性配置信息。它们分别遵循如下使用语法。 worker.list = < a comma separated list of worker names > worker. <worker name> .<property> = <property value> 其中worker.list指令可以重复指定多次。而worker name则是Tomcat中engine组件jvmRoute参数的值。如: worker.TomcatA.host=192.168.2.30 根据其工作机制的不同,worker有多种不同的类型,这是需要为每个worker定义的一项属性worker.<worker name>.type。常见的类型如下: 1.ajp13:此类型表示当前worker为一个运行着的Tomcat实例 2.lb: lb即load balancing,专用于负载均衡场景中的worker;此worker并不真正负责处理用户请求,而是将用户请求调度给其他类型为ajp13的worker。 3.status: 用于显示分布式环境中各实际worker工作状态的特殊worker,它不处理任何请求,也不关联到任何实际工作的worker实例。具体示例请参见后文中的配置。 worker其他常见的属性说明: 1.host: Tomcat 7的worker实例所在的主机; 2.port: Tomcat 7实例上AJP1.3连接器的端口; 3.connection_pool_minsize:最少要保存在连接池中的连接的个数;默认为pool_size/2; 4.connection_pool_timeout:连接池中连接的超时时长; 5.mount:由当前worker提供的context路径,如果有多个则使用空格隔;此属性可以由JKMount指令代替; 6.retries:错误发生时的重试次数; 7.socket_timeout:mod_jk等待worker响应的时长,默认为0,即无限等耐; 8.socket_keepalive:是否启用keep alive的功能,1表示启用,0表示禁用; 9.lbfactor:worker的权重,可以在负载均衡的应用场景中为worker定义此属性; 另外,在负载均衡模式中,专用的属性还有: 1.balance_workers:用于负载均衡模式中的各worker的名称列表,需要注意的是,出现在此处的worker名称一定不能再任何worker.list属性列表中定义过,并且worker.list属性中定义的worker名字必须包含负载均衡worker。具体示例请参见后文中的定义。 2.method:可以设定为R、T或B;默认为R,即根据请求的个数进行调度;T表示根据已经发送给worker的实际流量大小进行调度;B表示根据实际负载情况进行调度。 3.sticky_session:在将某请求调度至某worker后,源于此址的所有后续请求都将直接调度至此worker,实现将用户session与某worker绑定。默认值为1,即启用此功能。如果后端的各worker之间支持session复制,则可以将此属性值设为0. 根据前文中的指定,这里使用/etc/httpd/extra/workers。 properties来定义一个名为TomcatA的worker,并为其指定几个属性。文件内容如下: worker.list=TomcatA,stat1 worker.TomcatA.port=8009 worker.TomcatA.host=192.168.2.30 worker.TomcatA.type=ajp13 worker.TomcatA.lbfactor=1 worker.stat1.type = status 至此,一个基于mod_jk模块与后端名为TomcatA的worker通信的配置已经完成,重启httpd服务即可生效。 配置基于mod_jk的负载均衡 1、为了避免用户直接访问后端Tomcat实例,影响负载均衡的效果,建议在Tomcat 7的各实例上禁用HTTP/1.1连机器。 2、为每一个Tomcat 7实例的引擎添加jvmRoute参数,并通过其为当前引擎设置全局唯一标识符。如下所示,需要注意的是,每一个实例的jvmRoute的值均不能相同。 <Engine name="Standalone" defaultHost="localhost" jvmRoute="TomcatA"> 而后去配置apache,修改/etc/httpd/extra/httpd-jk.conf为如下内容: LoadModule jk_module modules/mod_jk.so JKWorkersFile /etc/httpd/extra/workers.properties JKLogFile logs/mod_jk.log JKLogLevel debug JKMount /* lbcluster1 JKMount /jkstatus/ stat1 编辑/etc/httpd/etra/workers.properties,添加如下内容:
worker.list = lbcluster1,stat1 worker.TomcatA.type = ajp13 worker.TomcatA.host = 192.168.2.30 worker.TomcatA.port = 8009 worker.TomcatA.lbfactor = 1 worker.TomcatB.type = ajp13 worker.TomcatB.host = 192.168.2.50 worker.TomcatB.port = 8009 worker.TomcatB.lbfactor = 1 worker.lbcluster1.type = lb worker.lbcluster1.sticky_session = 0 worker.lbcluster1.balance_workers = TomcatA, TomcatB worker.stat1.type = status
session cluster实现
通过内置组件session manager来实现
会话管理器(session manager)有: StandardManager PersistentManager FileStore JDBC DeltaManager BackupManager
构建session cluster示例:
(1)各节点配置使用deltamanager
# cd /usr/local/tomcat/conf # vim server.xml 在我们定义的虚拟主机内添加:
<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.1.7" //修改组播地址 port="45564" frequency="500" dropTime="3000"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto" //修改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.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>
(2)为需要使用session cluster的webapps开启session distribution的功能
# cp web.xml /data/webapps/ROOT/WEB-INF/ # vim /data/webapps/ROOT/WEB-INF/web.xml 在web-app中添加如下一行:
<distributable/>
另一个tomcat节点一样的配置
前端不需要其他修改即可正常工作,可以是http协议或是ajp协议,或是使用jk模块的形式。
会话管理器参考内容:
标准会话管理器和持久会话管理器 标准会话管理器(StandardManager) <Manager className="org.apache.catalina.session.StandardManager" maxInactiveInterval="7200"> 默认保存于¥CATALINA_HOME/work/Catalina/<hostname>/<webapp-name>/下的SESSIONS.ser文件中。 maxActiveSessions: 最多允许的活动会话数量,默认为-1,表示不限制 maxInactiveInterval:非活动的会话超时时长,默认为60s pathname:会话文件的保存目录 持久会话管理器(PersistentManager): 将会话数据保存至持久存储中,并且能在服务器意外中止后重新启动时重新加载这些会话信息。持久会话管理器支持将会话保存至文件存储(FileStore)或JDBC存储(JDBCStore)中。 保存至文件中的示例: <Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="true"> <Store className="org.apache.catalina.session.FileStore" directory="/data/tomcat-sessions"/> </Manager> 每个用户的会话被保存至directory指定的目录中的文件中,文件名为<session id>.session,并通过后台线程每隔一段时间(checkInterval参数定义,默认为60s)检查一次超时会话。 保存至JDBCStore中的示例: <Manager className="org.apache.catalina.session.PersistentManager" saveOnRestart="true"> <Store className="org.apache.catalina.session.JDBCStore" driverName="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/mydb?user=jb;password=pw" /> </Manager>
标签:selector status options 建议 请求 save 上下 root pes
原文地址:https://www.cnblogs.com/ckh2014/p/14435373.html