jboss集群session复制原理:

jboss session复制是jboss session同步的一种实现。原理是在各Jboss节点间建立横向联系,每个节点都将本节点的session变化同步到其他所有节点上。

jboss的session复制与HTTP集群是相互配合、相互独立的两个系统。session复制是节点间的横向联系,HTTP集群是负载均衡器与节点的纵向联系。

   10.0.2.203 – 安装JDK 1.6,JBoss 7,JBoss节点名称为jboss1

   10.0.2.202 – 安装JDK 1.6,JBoss 7,JBoss节点名称为jboss2

   10.0.2.200 – 安装Apache httpd,mod_jk  #需要在官网下载mod_jk模块,重命名为mod_jk,放置于/etc/httpd/modules 下



以下实验注意iptables 和 selinux 的影响。

 安装jdk和jboss 此处就不多说了,jboss不需要修改

  /usr/local/jboss-4.2.2.GA/server/all/deploy/jboss-web.deployer 目录下的

  server.xml文件的 <Connector port="8080" address="${jboss.bind.address}"默认地址,使用      mod_proxy时修改了此处。

  下面是apache 的配置:

  a:在/etc/httpd/conf.d/目录下创建mod_jk.conf文件,内容为:


LoadModule jk_module modules/mod_jk.so  #指定模块路径


JkWorkersFile conf.d/workers.properties  #指定mod_jk的workers定义


JkLogFile logs/mod_jk.log  #指定jk的日志输出文件


JkLogLevel info  #指定日志级别


JkLogStampFormat "[%a %b %d %H:%M:%S: %Y]"  #用来配置log文件的日期/时间格式. 使用strftime()的格式化字符串,默认是[%a %b %d %H:%M:%S %Y]

#Options Description(选项的说明)
# %b 发送的字节, 不包括 HTTP headers (CLF format)
# %B 发送的字节, 不包括 HTTP headers
# %H 协议
# %m 请求方式(get/post)
# %p 服务器响应请求的规范端口.
# %q 查询字符串 (如果存在以?开头,否则是空串)
# %r 请求的第一行.
# %s HTTP状态码
# %T 请求间隔, 处理请求耗费的时间 秒.微秒
# %U 请求的url路径,不包含查询字符串.
# %v 响应请求的规范服务器名字
# %V 根据UseCanonicalName设置的服务器名字.
# %w Tomcat worker 名字



JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories

JkRequestLogFormat "%w %V %T"   #设置个人用户请求的log格式


#JkMount /*  loadbalancer


JkMountFile conf.d/uriworkermap.properties  #加载workers的请求处理分配文件


#JkMount /* status


JkShmFile logs/jk.shm   #共享内存


<Location /jkstatus/>   对/jkstatus 新建访问控制

       JkMount status

       Order deny,allow

       Deny from all

       Allow from  10.0.2.0

</Location>

b:接着在/etc/httpd/conf.d/目录下创建workers.properties 文件,内容为:

worker.list=loadbalancer,status   # worker列表


worker.jboss1.port=8009    #ajp13 端口号

worker.jboss1.host=10.0.2.203

worker.jboss1.type=ajp13

worker.jboss1.lbfactor=1  #server的加权比重,值越高,分得的请求越多

worker.jboss1.cachesize=10


worker.jboss2.port=8009

worker.jboss2.host=10.0.2.202

worker.jboss2.type=ajp13

worker.jboss2.lbfactor=1

worker.jboss2.cachesize=10


#重试次数
worker.retries=3


worker.loadbalancer.type=lb  #用于负载均衡

worker.loadbalancer.balance_workers=jboss1,jboss2  #指定分担请求的server列表,用逗号分隔

worker.loadbalancer.sticky_session=1  #设置用于负载均衡的server的session可否共享
#一次请求中 session 只会在一个jboss上,当该jboss奔溃后,请求会跳转到其他jboss上,但是其session不会复制到跳转后的jboss上

worker.loadbalancer.sticky_session_force=0  #当jboss1崩溃后,请求转发到jboss2


worker.status.type=status  #描述是用于httpd自身状态监控的status

c:然后 在/etc/httpd/conf.d/目录下创建uriworkermap.properties 文件,内容为:

/*=loadbalancer    #所有请求都由loadbalancer这个server处理

/jkstatus=status    #所有包含jkstatus请求的都由status这个server处理


!/*.gif=loadbalancer   #所有以.gif结尾的请求都不由loadbalancer这个server处理,以下几个都是一样的意思

!/*.jpg=loadbalancer   #这里的"!”类似于java中的"!”,是“非”的意思

!/*.png=loadbalancer

!/*.css=loadbalancer

!/*.js=loadbalancer

!/*.htm=loadbalancer

!/*.html=loadbalancer

以下是jboss 实例的配置:

a:在10.0.2.203主机,编辑 $JBOSS_HOME/server/all/deploy/jboss-web.deployer/server.xml 文件

  <Engine name="jboss.web" defaultHost="localhost" jvmRoute="jboss1">

   在Engine 处添加 jvmRoute="jboss1",在10.0.2.202主机也相应地修改为jboss2


b:在10.0.2.203和10.0.2.202主机分别编辑 $JBOSS_HOME/server/all/deploy/jboss-web.deployer/

META-INF/jboss-service.xml 文件

<attribute name="UseJK">true</attribute>   #将UseJK的值改为true,使用mod_jk

c:在10.0.2.203和10.0.2.202主机分别编辑  

/usr/local/jboss-4.2.2.GA/server/all/deploy/jboss-web.deployer/conf/web.xml 文件

<?xml version="1.0"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"

version="2.4">

<distributable/>            #添加此项,开启jboss的session复制

<!-- ... -->

</web-app>

d:这里要做的是基于request的cluster,也就让各个节点之间互相复制session状态。有两种复制模式,同步与异步。使用同步的方式,jboss会把session复制的操作和对request的响应放到一个应用事务(application transaction),session复制完成后才去处理request。异步复制则发送session复制的消息后马上处理request,session复制则会稍有延迟。但是在多框架的web页面中,这样的集群方式会有问题。由于frame在同一时间发出多个request,会造成一些混乱,这也是采用基于用户的集群方式的原因之一。

<attribute name="CacheMode">REPL_ASYNC</attribute>

REPL_ASYNC(异步)或者REPL_SYNC(同步)。

attribute name="ClusterName"> 这个属性是设置你的集群的名字

在下面还有个<attribute name="ClusterConfig"> 这个属性是设置每个节点在进行session复制的时候是如何通信的,有TCP和UDP两种,默认使用UDP。如果使用udp方式,那么应该将udp的lookback属性指定为true。采用UDP方式问题比较多,所以采用TCP方式,应该指定bind_addr的值为本机ip,并且在TCPPING标签的initial_hosts属性中列出所有节点,格式是”机器名[端口号]”,将<TCP>到</TCP>标签内的全部down_thread和up_thread的false都改为true。还需要注释掉<!--<config><udp>...</udp></config>-->。

e:在10.0.2.203和10.0.2.202 主机写index.jsp测试页面,放置于/usr/local/jboss-4.2.2.GA/server/all/deploy/jboss-web.deployer/ROOT.war 目录下,内容为:

<%@ page contentType="text/html; charset=GBK" %>

<%@ page import="java.util.*" %>

<html><head><title>Cluster App Test</title></head>

<body>

Server Info:

<%

out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%>

<%

out.println("<br> ID " + session.getId()+"<br>");

String dataName = request.getParameter("dataName");

if (dataName != null && dataName.length() > 0) {

String dataValue = request.getParameter("dataValue");

session.setAttribute(dataName, dataValue);

}

out.print("<b>Session list</b>");

Enumeration e = session.getAttributeNames();

while (e.hasMoreElements()) {

String name = (String)e.nextElement();

String value = session.getAttribute(name).toString();

out.println( name + " = " + value+"<br>");

System.out.println( name + " = " + value);

}

%>

%<form action="index.jsp" method="POST">

%id:<input type=text size=20 name="dataName">

%<br>

%key:<input type=text size=20 name="dataValue">

%<br>

%<input type=submit>

%</form>

%</body>

%</html>

最后浏览器访问:10.0.2.90/jkstatus

134541961.jpg

134713756.jpg

135033624.jpg

可以从jkstatus看到关于设置的大量信息

浏览器访问10.0.2.90/index.jsp

135515667.jpg

接着填写内容并提交

135659936.jpg

可以看到提交的内容并sticky在一台jboss实例

135816282.jpg

此时将jboss1停掉,可以看到session在jboss2上面,提交内容,再启动jboss1,停掉jboss2,可以看到session在jboss1上面。(此实验session从jboss2到jboss1有点问题,待解决)


查看/usr/local/jboss-4.2.2.GA/server/all/deploy/jboss-web-cluster.sar/META-INF目录下的jboss-web.xml 文件:

ClusterName是集群名称,
在同一局域网内,可以存在多个jboss集群,根据集群名称区分它们.所以,集群中各节点配置的集群名称必须一致,而机器IP则没有特殊要求,只要它们能相互连通. 理论上,可以在一台机器上安装多个Jboss实例,分属于不同的集群.但这会极大地增加复杂度,是不好的配置方式.

IsolationLevel是隔离等级.
可选值包括:SERIALIZABLE, REPEATABLE_READ, READ_COMMITTED, READ_UNCOMMITTED, 和 NONE。这里的隔离级别和数据库的隔离级别有同样的含义,对于大多数WEB应用程序来讲通常设置为REPEATABLE_READ。

CacheMode是缓存模式。
由于session复制是通过缓存实现的,所以实际上是复制模式.可选值包括:REPL_SYNC 和REPL_ASYNC,确定改变是应该同步还是异步复制。缺省值是REPL_ASYNC.使用同步复制,确保在请求完成之前传播改变,session同步没有滞后,但效率低。