月度归档:2011年06月

Tomcat 6.x 和 Apache 2.2.11 集群负载均衡搭建

本文根据 http://www.cnblogs.com/shiyangxt/archive/2009/02/26/1398902.html 整理,如有不明,请参阅原文。
  1. 所需软件:
  • Apache 2.2.11
  • Tomcat 6.x压缩版(.zip, .tar等压缩格式的版本)。

2. 配置步骤:

1) 安装Apache 2.2.11tomcat 集群负载均衡需要apache服务器来配合实现,所以我们需要安装apache。另外,由于apache 2.2.11已经集成了jk2等负载工具,这将简化我们的配置。可以用安装版或解压版安装apache

    • 如果用windows下安装版安装,根据向导填写相应参数即可完成。
    • 如果用压缩版,需要将apache解压到一个目录下面,然后打开$APACHE_HOME/conf/httd.conf, 根据实际配置下面参数:

#apache安装根目录

ServerRoot "D:/devCenter/cluster_lab/Apache2.2 "

#端口

Listen 80

#

ServerAdmin 邮件

#http文档根目录

DocumentRoot "D:/devCenter/cluster_lab/Apache2.2/htdocs"

#

# This should be changed to whatever you set DocumentRoot to.

#

<Directory "D:/devCenter/cluster_lab/Apache2.2/htdocs">

#

# Possible values for the Options directive are "None", "All",

# or any combination of:

# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews

#

# Note that "MultiViews" must be named *explicitly* — "Options All"

# doesn't give it to you.

#

# The Options directive is both complicated and important. Please see

# http://httpd.apache.org/docs/2.2/mod/core.html#options

# for more information.

Options Indexes FollowSymLinks

#

# AllowOverride controls what directives may be placed in .htaccess files.

# It can be "All", "None", or any combination of the keywords:

# Options FileInfo AuthConfig Limit

#

AllowOverride None

 

#

# Controls who can get stuff from this server.

#

Order allow,deny

Allow from all

</Directory>

<IfModule alias_module>

# directives as to Alias.

ScriptAlias /cgi-bin/ "D:/devCenter/cluster_lab/Apache2.2/cgi-bin/"

</IfModule>

#

# "D:/devCenter/cluster_lab/Apache2.2/cgi-bin" should be changed to whatever your ScriptAliased

# CGI directory exists, if you have that configured.

#

<Directory "D:/devCenter/cluster_lab/Apache2.2/cgi-bin">

AllowOverride None

Options None

Order allow,deny

Allow from all

</Directory>

2) 启动apache, 然后通过http://localhost/来测试,检查apache是否已经启动。

3) 启用负载均衡相关的module, 打开$APACHE_HOME/conf/httd.conf,去掉以下文本前的注释符(#)以便让Apache在启动时自动加载代理(proxy)模块:

LoadModule proxy_module modules/mod_proxy.so

LoadModule proxy_ajp_module modules/mod_proxy_ajp.so

LoadModule proxy_balancer_module modules/mod_proxy_balancer.so

LoadModule proxy_connect_module modules/mod_proxy_connect.so

LoadModule proxy_ftp_module modules/mod_proxy_ftp.so

LoadModule proxy_http_module modules/mod_proxy_http.so

4)配置IfModule dir_module节点:找到<IfModule dir_module>节点,在DirectoryIndex index.html后加上index.jsp,这一步只是为了待会配置完tomcat后能看到小猫首页,可以不做。

5)配置httpd-vhosts.conf中的虚拟主机:打开$APACHE_HOME/conf/extra/httpd-vhosts.conf, 在最下面添加以下信息:

<VirtualHost *:80>

ServerAdmin 管理员邮箱

ServerName localhost

ServerAlias localhost

ProxyPass / balancer://sy/ stickysession=jsessionid nofailover=On

ProxyPassReverse / balancer://sy/

ErrorLog "logs/sy-error.log"

CustomLog "logs/sy-access.log" common

</VirtualHost>

然后在$APACHE_HOME/conf/httd.conf, 启用下面配置:
# Virtual hosts
Include conf/extra/httpd-vhosts.conf

6)打开$APACHE_HOME/conf/httd.conf,在最下面添加以下信息:

ProxyRequests Off

<proxy balancer://sy>

BalancerMember ajp://127.0.0.1:8009 loadfactor=1 route=jvm1

BalancerMember ajp://127.0.0.1:9009 loadfactor=1 route=jvm2

</proxy>

ProxyRequests Off 是告诉Apache需要使用反向代理,ip地址和端口唯一确定了tomcat节点和配置的ajp接受端口。loadfactor是负载因子,Apache会按负载因子的比例向后端tomcat节点转发请求,负载因子越大,对应的tomcat服务器就会处理越多的请求,如两个tomcat都是1Apache就按11的比例转发,如果是21就按21的比例转发。这样就可以使配置更灵活,例如可以给性能好的服务器增加处理工作的比例,如果采取多台服务器,只需要修改ip地址和端口就可以了。route参数对应后续tomcat配置中的引擎路径(jvmRoute)。

7) 解压tomcat 到一个目录,并复制一份。然后打开两个tomcat下面conf/server.xml

注意:如果tomcat在不同机器上面,端口可以使用默认值。

o 配置关闭端口:其中一个tomcat<Server port="8005" shutdown="SHUTDOWN">保持不变,将另一个的端口修改为9005.

o 配置Connector的端口:找到non-SSL HTTP/1.1 Connector,即tomcat单独工作时的默认Connector,保留第一台默认配置,在8080端口侦听,而把第二台设置为在9080端口侦听。往下找到AJP 1.3 Connector<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />,这是tomcat接收从Apache过来的ajp连接请求时使用的端口,保留第一台默认设置,把第二台端口改为9009

o 配置jvmRoute:第一台tomcatserver.xml中找到<Engine name="Catalina" defaultHost="localhost">,去掉这段或改为注释,把上方紧挨的<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">注释符去掉,对于第二台,去掉注释符并把jvm1改为jvm2

o 配置Cluster:将两个tomcatserver.xml<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" />的注释去掉。这里的配置是为了可以在集群中的所有tomcat节点间共享会话(Session)。如果仅仅为了获得一个可用的tomcat集群,Cluster只需要这么配置就可以了。

8) 测试:

       只需要简单的几步就配置完成,然后可以测试一下是否配置成功。引用网上的一个测试方法,就是在webapps目录下新建test目录,在test目录下新建test.jsp文件,代码我稍作改动如下:

<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<html><head><title>shiyang</title></head>
<body>
服务信息:
<%
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 列表</b><br />");
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="test.jsp" method="POST">
名称:<input type=text size=20 name="dataName">
<br/>
:<input type=text size=20 name="dataValue"> <br/> <input type=submit value="提交">
</form>
</body>
</html>

       在test目录下继续新建WEB-INF目录和web.xml,在<web-app>节点下加入<distributable />,这一步非常重要,是为了通知tomcat服务器,当前应用需要在集群中的所有节点间实现Session共享。如果tomcat中的所有应用都需要Session共享,也可以把conf/context.xml中的改为<Context>改为<Context distributable="true">,这样就不需对所有应用的web.xml再进行单独配置。测试代码完成! 先启动Apache服务,在先后启动两台tomcat,分别点startup.bat批处理。如果一切顺利的话,就会启动成功。再次访问http://localhost,可以看到小猫页面。访问http://localhost/test/test.jsp。可以看到包括服务器地址,端口,session等信息在内的页面。然后你可以测试一下容错功能,关闭一个tomcat,看看服务是否正常,然后重启tomcat,关掉另一台tomcat,看看是否也可以继续提供服务。当然你也可以配置多台tomcat,但是原理都一样。

 

其它更加详细的配置可以参考 http://tomcat.apache.org/tomcat-6.0-doc/cluster-howto.html 和  http://tomcat.apache.org/tomcat-6.0-doc/balancer-howto.html

 

作者:豆博草堂

图灵机、工作流

        今天我开始根据需求设计我们的ER-图了。 然而我们项目里面有很多流程,为了简化开发,部门提出采用JBPM , 然而,我们以前还没有项目使用过它。为了在目前项目中迅速采用JPBM, 同时也想了解下它可以给我们带来的好处,我就开始上网调查它,发现JBPM看起来好庞大,显得有些复杂。但基本明白了一点:根据xml中定义的流程来动态调用不同的方法。然而,由于对JPBM的不熟悉,我却突然不知如何设计我们的ER-图、数据库表了,以前我们的流程我都会通过在表中加stepOwner(所属阶段)相关属性来控制流程流转的。 JPBM对我来说有些复杂,我需要一个简单的流程引擎。 细细想来,流程其实就是图灵机的变体,只不节点的粒度大了些,但都是根据当前状态来确定下一步动作,然后更新状态。鉴于这种考虑,我想设计一个简单的流程辅助工具(不能称为引擎,引擎所表达的功能太过强大。)。 下图就是我设计的简单工作流的执行过程: 执行过程基本就是:根据当前所处的处理阶段和状态码到工作流定义库中查询要执行的动作,然后执行相应动作, 执行完之后根据工作流定义更新流程相应的阶段和状态码。 工作流定义为:

REC

字段名称

数据类型

长度

可空

Key

说明

1

key

varchar2

50

NO

YES

规则键值

2

stepOwner

varchar2

50

NO

YES

所属阶段

3

currentState

varchar2

50

NO

YES

当前状态

4

action

300

50

YES

NO

在当前阶段、当前状态采取的动作。

5

priority

int

4

NO

NO

优先级:<stepOwner,currentState>下,优先级值小的优先选择。(用户在代码中可以优先选取。)

6

afterStepOwner

varchar2

50

NO

NO

动作执行之后的阶段所属角色。

7

afterState

varchar2

50

NO

NO

动作执行之后的状态标识。

 
 
 
 
 
 
 
 
 
 
 
 
 
 

 

 
 
 
 
举例来说,有下面一个流程,
要在workFollow表中描述这个流程,我们可以在表中添加下面这些记录(省略了key和priority字段):
REC stepOwner currentState action afterStepOwner afterState
1 ROLE_A EDIT_DOCUMENT SUBMIT ROLE_B WAIT_AUDIT
2 ROLE_B WAIT_AUDIT AUDIT_ACCEPT NONE NONE
3 ROLE_B WAIT_AUDIT AUDIT_REJECT ROLE_A EDIT_DOCUMENT
其中, 第一条表示:在Role A 处理时,如果处于编辑文档状态(EDIT_DOCUMENT),则执行提交动作(SUBMIT),提交后处理阶段变为 Role B, 状态变为等待审核(WAIT_AUDIT)。 第二条和第三条:在Role B处理时,如果文档处于等待审核状态(WAIT_AUDIT),Role B可以执行两种动作,审核通过(AUDIT_ACCEPT)和不通过(AUDIT_REJECT)。如果通过, 则结束,即将所处阶段置和状态为NONE。不通过时,将阶段置为Role A(ROLE_A), 将状态置为编辑文档(EDIT_DOCUMENT) 当然,为了记录驱动我们工作流的两个关键属性:所属阶段(stepOwner)和当前状态(currentState), 我们需要在我们的业务属性表中添加这两个字段。 有了这个基本模型后,我们就可以将流程分离到数据库中,用工作流定义来驱动程序走向。这就是我这两天设计的SimpleWorkFollow。这个简单的工作流我正在逐步完善中,但我绝不会让它变的复杂。希望这些思想对大家有所帮助。 我们项目是使用JBPM还是我这个简单的工作流有待评估。因为我们的流程很复杂,而且不同流程之间有很多关联。

作者:豆博草堂