首页 > 代码库 > Tomcat Cluser 集群服务

Tomcat Cluser 集群服务

Tomcat Cluser 

===============================================================================

概述:


===============================================================================

Tomcat Cluster

 1.会话保持

方法:

session sticky(粘性)

  • source ip    //原地址哈希

  • cookie

  • hash HEADER

注意:

  • 后面两种方式要确保前端调度器为7层负载均衡,如nginx,haproxy

session cluser(集群)

缺陷:

  • 每一个节点都将会持有整个集群中的所有会话信息,因为会话会保存在内存中,所以将会非常占用内存资源;

  • 此种方式不适合集群规模节点较大的场景使用;

session server(粘性)

  • 会话保存在一个第三方的独立外部存储设备上,使得会话在集群中的各节点得到共享;

缺陷:

  • 每一次session信息的获取都要通过第三方服务器来加载,会产生网络IO;

  • 同时还要保证 session server  服务器足够强大,即事务能力要无与伦比,一般不使用关系型数据库,而是采用 kv 存储并基于内存来提供服务。

常用于session server的服务器:

  • memcached,redis(推荐使用)

 2.Tomcat Cluser

三种方式

(1) session stickey 会话粘性的方式:

前端调度器可以为

  • nginx

  • haproxy

  • lvs

  • httpd

(2) session cluster 会话集群的方式:

  • tomcat delta manager

  • tomcat session cluster 

注意:

  • 此种方式前端仍然需要一个调度器,但是不需要做会话绑定,会话由 tomcat 自己实现;

(3) session server 会话服务器的方式

  • memcached;

  • redis;

注意:

生产环境中,一般采用的架构模型为第三种,通过session server 来维持会话;具体实现如下:

  • 前端调度器可以为nginx,haproxy等实现负载均衡,中间web server为 amt 即通过httpd和tomcat结合的方式实现(多个),后端为 session server;前端调度器实现动静分离,将动态内容(.jsp|do)调度到中间的 httpd,然后再通过httpd 反代至 tomcat 实例,多个httpd+tomcat 通过后端的 session server 实现会话共享;

附图:

技术分享

 3.apache + tomcatS:

结合方式:

http协议

apache:

  • mod_proxy

  • mod_proxy_http

  • mod_proxy_balancer

tomcat

  • http connector

ajp协议

apache:

  • mod_proxy

  • mod_proxy_ajp

  • mod_proxy_balancer

tomcat

  • ajp connector

mod_jk

apache:

  • mod_jk

tomcat

  • ajp connector

实验:第一种方法 http 的实现:



环境描述:

  • 准备3台虚拟主机(我这里为 centos7),一台作为httpd调度器,两台作为后端的tomcat服务器;实现httpd反代用户请求至后端的两台tomcat服务器;

  • 两台tomcat主机的ip为 node1:192.168.1.112;node2:192.168.1.113;httpd 调度器的ip:192.168.1.114

实验环境准备:

1.首先准备两台后端的 tomcat 主机(部署好JDK环境,过程详见前面内容),并提供测试页面,这里以node2(openjdk)为例:

[root@node2 webapps]# pwd
/var/lib/tomcat/webapps

[root@centos7 webapps]# mkdir -pv ./testapp/{classes,lib,WEB-INF,META-INF}
mkdir: created directory ‘./testapp’
mkdir: created directory ‘./testapp/classes’
mkdir: created directory ‘./testapp/lib’
mkdir: created directory ‘./testapp/WEB-INF’
mkdir: created directory ‘./testapp/META-INF’
[root@centos7 webapps]# ls
docs  examples  host-manager  manager  ROOT  sample  testapp
[root@centos7 webapps]# ls testapp/
classes  lib  META-INF  WEB-INF

# 提供测试页面
[root@node2 testapp]# cat index.jsp 
<%@ page language="java" %>
<%@ page import="java.util.*" %>
<html>
		<head>
			<title>Test Page</title>
		</head>
		<body>
			<% out.println("Tomcat B");
			%>
		</body>
</html>

 为了能够保证能够访问到testapp,在/etc/tomcat/server.xml中的 Host 中定义Context 如下:

技术分享

 启动tomcat服务,在浏览器中访问如下:

技术分享

创建向后端反代的虚拟主机

1.在http调度器上创建一个向后端反代虚拟主机,如下:

[root@centos7 conf.d]# pwd
/etc/httpd/conf.d

[root@centos7 conf.d]# cat mod_proxy_http.conf 
<proxy balancer://tcsrvs>
	BalancerMember  loadfactor=1  # 设定权重
	BalancerMember  loadfactor=2
	ProxySet lbmethod=byrequests
</proxy>

<VirtualHost *:80>
	ServerName lb.taotao.com
	ProxyVia On
	ProxyRequests Off
	ProxyPreserveHost On
	<Proxy *>
		Require all granted
	</Proxy>
	ProxyPass / balancer://tcsrvs/
	ProxyPassReverse / balancer://tcsrvs/
	<Location />
		Require all granted
	</Location>
</VirtualHost>

# 检查语法,启动httpd服务
[root@centos7 conf.d]# httpd -t
Syntax OK
[root@centos7 conf.d]# systemctl start httpd

测试如下:

[root@centos7 conf.d]# curl http://192.168.1.114/test/


<html>
		<head>
			<title>Test Page</title>
		</head>
		<body>
			Tomcat A

		</body>
</html>
[root@centos7 conf.d]# curl http://192.168.1.114/test/


<html>
		<head>
			<title>Test Page</title>
		</head>
		<body>
			Tomcat B

		</body>
</html>
[root@centos7 conf.d]# curl http://192.168.1.114/test/


<html>
		<head>
			<title>Test Page</title>
		</head>
		<body>
			Tomcat B

		</body>
</html>
[root@centos7 conf.d]# curl http://192.168.1.114/test/


<html>
		<head>
			<title>Test Page</title>
		</head>
		<body>
			Tomcat A

		</body>
</html>

2.会话粘性的实现方法:(不常用)

[root@centos7 conf.d]# cat mod_proxy_http.conf 
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED

<proxy balancer://tcsrvs>
	BalancerMember http://192.168.1.112:8080 route=TomcatA loadfactor=1
	BalancerMember http://192.168.1.113:8080 route=TomcatB loadfactor=2
	ProxySet lbmethod=byrequests
	ProxySet stickysession=ROUTEID
</proxy>

<VirtualHost *:80>
	ServerName lb.taotao.com
	ProxyVia On
	ProxyRequests Off
	ProxyPreserveHost On
	<Proxy *>
		Require all granted
	</Proxy>
	ProxyPass / balancer://tcsrvs/
	ProxyPassReverse / balancer://tcsrvs/
	<Location />
		Require all granted
	</Location>
</VirtualHost>

3.启用管理接口

[root@centos7 conf.d]# cat mod_proxy_http.conf 
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED

<proxy balancer://tcsrvs>
	BalancerMember http://192.168.1.112:8080 route=TomcatA loadfactor=1
	BalancerMember http://192.168.1.113:8080 route=TomcatB loadfactor=2
	ProxySet lbmethod=byrequests
	ProxySet stickysession=ROUTEID
</proxy>

<VirtualHost *:80>
	ServerName lb.taotao.com
	ProxyVia On
	ProxyRequests Off
	ProxyPreserveHost On
	<Proxy *>
		Require all granted
	</Proxy>
	ProxyPass / balancer://tcsrvs/
	ProxyPassReverse / balancer://tcsrvs/
	<Location />
		Require all granted
	</Location>
	<Location /balancer-manager>    # 启用管理接口
		SetHandler balancer-manager
		ProxyPass !
		Require all granted
	</Location>
</VirtualHost>

在浏览器中访问如下:

技术分享


实验:第二种方法 ajp 协议的实现:



ajp协议的实现和http协议在实现方式上基本相同,不同的就是所用的协议不同,监听的端口不同,配置方式如下:

[root@centos7 conf.d]# cat mod_proxy_http.conf
<proxy balancer://tcsrvs>
	BalancerMember ajp://192.168.1.112:8009 loadfactor=1
	BalancerMember ajp://192.168.1.113:8009 loadfactor=2
	ProxySet lbmethod=byrequests
</proxy>

<VirtualHost *:80>
	ServerName lb.taotao.com
	ProxyVia On
	ProxyRequests Off
	ProxyPreserveHost On
	<Proxy *>
		Require all granted
	</Proxy>
	ProxyPass / balancer://tcsrvs/
	ProxyPassReverse / balancer://tcsrvs/
	<Location />
		Require all granted
	</Location>
	<Location /balancer-manager>
		SetHandler balancer-manager
		ProxyPass !
		Require all granted
	</Location>
</VirtualHost>

管理接口如下:

技术分享实验:第三种方法 mod_jk 模块的实现:



步骤如下:

技术分享

技术分享

Tomcat Session Replication Cluster:

session会话保持之session服务器

1.环境:

  • 两个tomcat节点:172.16.100.7(tomcatA.magedu.com) 172.16.100.8(tomcatB.magedu.com)

  • 两个memcached节点:172.16.100.9, 172.16.100.10

  • 一个负载均衡节点:172.16.100.6

2.memcached-session-manager项目地址:

  • http://code.google.com/p/memcached-session-manager/

   下载如下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

3.步骤如下:

1)分别在两个tomcat上的某host上定义一个用于测试的context容器,并在其中创建一个会话管理器,如下所示:

<Context path="/test" docBase="/usr/local/tomcat/webapps/test" reloadable="true">
   <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
    memcachedNodes="n1:172.16.100.9:11211,n2:172.16.100.10:11211"
    failoverNodes="n1"
    requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
    transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"
   />
</Context>

2)分别为两个context提供测试页面:

  tomcatA

# mkdir -pv /usr/local/tomcat/webapps/test/WEB-INF/{classes,lib}
# vim /usr/local/tomcat/webapps/test/index.jsp
添加如下内容:
<%@ page language="java" %>
<html>
  <head><title>TomcatA</title></head>
  <body>
    <h1><font color="red">TomcatA.magedu.com</font></h1>
    <table align="centre" border="1">
      <tr>
        <td>Session ID</td>
    <% session.setAttribute("magedu.com","magedu.com"); %>
        <td><%= session.getId() %></td>
      </tr>
      <tr>
        <td>Created on</td>
        <td><%= session.getCreationTime() %></td>
     </tr>
    </table>
  </body>
</html>

  tomcat B

# mkdir -pv /usr/local/tomcat/webapps/test/WEB-INF/{classes,lib}
# vim /usr/local/tomcat/webapps/test/index.jsp
添加如下内容:
<%@ page language="java" %>
<html>
  <head><title>TomcatB</title></head>
  <body>
    <h1><font color="blue">TomcatB.magedu.com</font></h1>
    <table align="centre" border="1">
      <tr>
        <td>Session ID</td>
    <% session.setAttribute("magedu.com","magedu.com"); %>
        <td><%= session.getId() %></td>
      </tr>
      <tr>
        <td>Created on</td>
        <td><%= session.getCreationTime() %></td>
     </tr>
    </table>
  </body>
</html>

3)在172.16.100.6上配置反向代理的负载均衡内容,类似如下所示:

<Proxy balancer://tomcat>
    BalancerMember  http://172.16.100.7:8080 loadfactor=1
    BalancerMember  http://172.16.100.8:8080 loadfactor=1
    ProxySet  lbmethod=byrequests
</Proxy>

ProxyVia Off
ProxyRequests Off
ProxyPass / balancer://tomcat/
ProxyPassReverse / balancer://tomcat/
<Proxy *>
    Order Allow,Deny
    Allow From all
</Proxy>

<Location />
    Order Allow,Deny
    Allow From all
</Location>

4)测试结果,在浏览器中访问http://172.16.100.6/test,结果如下所示,其session ID在负载均衡环境中保持不变。

TomcatA.magedu.com

Session ID	4DD0340CE6294FF2BBE802CD4CD039EC-n2
Created on	1399890838103


TomcatB.magedu.com

Session ID	4DD0340CE6294FF2BBE802CD4CD039EC-n2
Created on	1399890838103







本文出自 “逐梦小涛” 博客,请务必保留此出处http://1992tao.blog.51cto.com/11606804/1909351

Tomcat Cluser 集群服务