共计 6483 个字符,预计需要花费 17 分钟才能阅读完成。
CentOS-6.4-minimal 版中 Apache-2.2.29 与 Tomcat-6.0.41 实现集群
———————————————————————————————————————-
本文建立在 Apache-2.2.29 与 Tomcat-6.0.41 实现负载均衡的基础上, 实现过程详见 http://www.linuxidc.com/Linux/2014-09/107337.htm
———————————————————————————————————————-
几个术语
1) 负载均衡
前端服务器(常常名为 ” 负载均衡器 ”,” 代理均衡器 ” 或 ” 反向代理 ”) 收到 HTTP 请求后, 将请求分发到后端的不止一个 ”worker” 的 web 服务器, 由它们实际处理请求
2) 会话复制
会话复制(即常说的 Session 共享) 是一种机制, 将客户端会话的整个状态原原本本复制到集群中的两个或多个服务器实例, 以实现容错和故障切换功能
3) 集群
集群由两个或多个 Web 服务器实例组成, 这些服务器实例步调一致地工作, 透明地处理客户端请求, 客户端将一组服务器实例认为是单一实体服务
———————————————————————————————————————-
几个区别
1) 集群有别于分布式的解决方案, 它采用的是每台服务器运行相同应用的策略, 由负责均衡的服务器进行分流, 这可以提高整个系统的并发量及吞吐量
2) 由于集群服务需要在处理请求之间不断地进行会话复制, 复制后的会话将会慢慢变得庞大, 因此它的资源占用率是非常高的
如果在并发量大的应用中, 复制的会话大小会变得相当大, 而使用的总内存更是会迅速升高
3) 集群的会话复制, 增加了系统的高可用性, 由于在每台服务器都保存有用户的 Session 信息
如果服务器群中某台宕机, 应用可以自动切换到其它服务器上继续运行, 而用户的信息不会丢失, 这提高了应用的冗错性
4) 实践证明, 在各应用服务器之间不需要状态复制的情况下, 负载均衡可以达到性能的线性增长及更高的并发需求
———————————————————————————————————————-
配置集群的 Tomcat 实例的名称
这里 jvmRoute 属性值要与 workers.properties 中设置的节点名相同, 该值将做为后缀添加在每个由该结点生成的 jsessionid 后面
而 mod_jk 正是根据 jsessionid 后面的后缀来确定一个请求应由哪一个结点来处理, 这也是实现 session_sticky 的基本保证
[root@CentOS64 app]# vi /app/tomcat1/conf/server.xml (为 <Engine/> 节点增加 jvmRoute 属性, 属性值为 tomcat1)
[root@CentOS64 app]# vi /app/tomcat2/conf/server.xml (为 <Engine/> 节点增加 jvmRoute 属性, 属性值为 tomcat2)
[root@CentOS64 app]# vi /app/tomcat3/conf/server.xml (为 <Engine/> 节点增加 jvmRoute 属性, 属性值为 tomcat3)
———————————————————————————————————————-
配置集群参数
0) 如果 tomcat 是放在不同机器上面的
那么直接取消注释 tomcat/conf/server.xml 中的 <Cluster className=”org.apache.catalina.ha.tcp.SimpleTcpCluster”/> 即可
1) 如果 tomcat 是放在同一机器上面的 (参考 http://tomcat.apache.org/tomcat-6.0-doc/cluster-howto.html)
此时就要修改 <Cluster/> 节点的默认配置, 其默认配置如下
<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.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>
我们要做的就是显式添加此默认配置, 并修改上面的 Receiver port, 由于我们这里有三个 tomcat 节点, 故这个端口就依次修改为 4001,4002,4003
之所以没有修改为 4100,4200,4300, 是由于 Tomcat 官方建议此端口范围在 4000~4100 之间
———————————————————————————————————————-
应用程序为集群做的准备
1)Session 中存放的数据必须实现序列化
2) 在应用程序的 web.xml 中加入 <distributable/> 元素
———————————————————————————————————————-
测试集群
启动 apache 和 3 个 tomcat 后, 测试方法如下 (测试代码已在下方列出)
1) 访问测试页面, 会看到页面打印 SessionID 后面多出了 ”.tomcat2″, 这就是上文说到的 jsessionid 后面会加上.jvmRoute 为后缀, 表明 tomcat2 在处理此请求
2) 刷新测试页面, 会看到打印的 SessionID 没有变化 (与负载均衡后的效果有明显不同, 详见 http://www.linuxidc.com/Linux/2014-09/107337.htm)
3) 添加新的属性, 提交表单后会发现打印出了新添加的属性名和属性值, 接着刷新页面会发现添加的属性依然存在
4) 最关键的一步, 关闭 tomcat2 服务器, 再刷新页面, 会发现请求交由 ”tomcat1″ 来处理了, 并且之前添加的属性依然存在.. 至此,Session 共享成功,集群成功
———————————————————————————————————————-
注意事项
1)java.net.BindException: Cannot assign requested address; No faulty members identified
启动 tomcat 时报告上面的异常, 猜测可能是由于 tomcat 安装在我的虚拟机中, 该属性导致其与我的主机(Thinkpad 笔记本) 的 IP 产生冲突
此时修改[address=”auto”] 中 auto 为 192.168.0.103(即 tomcat 服务器的 IP)即可.. 如果还报这个异常, 可以试一下 127.0.0.1
2)如果仍然启动失败, 或者启动成功, 但无法实现 session 共享, 那么有可能是组播出现了问题
因为 tomcat 中的集群原理是通过组播的方式进行节点的查找并使用 TCP 连接进行会话的复制的, 即 tomcat 的 session 同步功能需要用到组播服务
可以通过[route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0] 命令开通 Linux 组播服务
如果需要服务器启动时即开通组播, 则需 /etc/sysconfig/static-routes 文件中加入[eht0 net 224.0.0.0 netmask 240.0.0.0]
另外, 可以通过[netstat -g] 或者 [route -e] 命令来查看组播状态
———————————————————————————————————————-
@create Sep 27, 2014 7:59:32 PM
@author 玄玉 <http://www.linuxidc.com>
<%@ page language=”java” pageEncoding=”UTF-8″%>
<%
out.println(“<br>Session ID : ” + session.getId() + “<br>”);
session.setAttribute(“myname”, “session”);
String dataName = request.getParameter(“dataName”);
if(null!=dataName && dataName.length()>0){
String dataValue = request.getParameter(“dataValue”);
session.setAttribute(dataName, dataValue);
}
out.print(“<b>Session 列表 </b><br>”);
java.util.Enumeration e = session.getAttributeNames();
while(e.hasMoreElements()){
String name = (String)e.nextElement();
String value = session.getAttribute(name).toString();
out.println(name + ” = ” + value+”<br>”);
}
%>
<form action=”demo.jsp” method=”POST”>
属性名:<input type=text size=20 name=”dataName”><br>
属性值:<input type=text size=20 name=”dataValue”><br>
<input type=submit>
</form>
在 Ubuntu 12.04 LTS 上通过 Tomcat 部署 Solr 4 http://www.linuxidc.com/Linux/2012-09/71158.htm
Ubuntu 下部署 Solr(4.4)到 Tomcat(7.0.53) http://www.linuxidc.com/Linux/2014-05/101443.htm
Linux 下 Apache 与多个 Tomcat 集群负载均衡 http://www.linuxidc.com/Linux/2012-01/51731.htm
Nginx Tomcat 集群负载均衡解决笔记 http://www.linuxidc.com/Linux/2013-07/86827.htm
实例详解 Tomcat 组件安装 +Nginx 反向代理 Tomcat+Apache 使用 mod_jk 和 mod_proxy 反向代理和负载均衡 http://www.linuxidc.com/Linux/2013-06/85290.htm
CentOS 6.5 下利用 Rsyslog+LogAnalyzer+MySQL 部署日志服务器 http://www.linuxidc.com/Linux/2014-06/103836.htm
Apache+Tomcat 环境搭建(JK 部署过程)http://www.linuxidc.com/Linux/2012-11/74474.htm
Tomcat 的详细介绍:请点这里
Tomcat 的下载地址:请点这里
更多 CentOS 相关信息见CentOS 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=14