1.安装httpd-devel
rpm -ivh apr-devel-1.3.9-3.el6.x86_64.rpm rpm -ivh db4-cxx-4.7.25-16.el6.x86_64.rpm rpm -ivh db4-devel-4.7.25-16.el6.x86_64.rpm rpm -ivh expat-devel-2.0.1-9.1.el6.x86_64.rpm rpm -ivh cyrus-sasl-devel-2.1.23-8.el6.x86_64.rpm rpm -ivh openldap-devel-2.4.19-15.el6.x86_64.rpm rpm -ivh apr-util-devel-1.3.9-3.el6.x86_64.rpm rpm -ivh httpd-devel-2.2.15-5.el6.x86_64.rpm
或
yum -y install httpd-devel.*
2.下载:
jdk-6u45-linux-x64.bin apache-tomcat-6.0.37.tar.gz apache-tomcat-6.0.37-src.tar.gz
将文件放入/opt谁的夹中
3.安装
mv tomcat-connectors-1.2.37-src.tar.gz /opt tar -xzvf tomcat-connectors-1.2.37-src.tar.gz mv jdk-6u45-linux-x64.bin /opt chmod u+x jdk-6u45-linux-x64.bin /opt mv apache-tomcat-6.0.37.tar.gz /opt tar -xzvf apache-tomcat-6.0.37.tar.gz mv apache-tomcat-6.0.37 tomcat ./jdk-6u45-linux-x64.bin mv jdk1.6.0_45 jdk
在/etc/profile文件中增加以下内容
JAVA_HOME=/opt/jdk CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH export JAVA_HOME PATH CLASSPATH
让环境变量生效可通过重新启动或执行以下命令
source /etc/profile
以下转自:http://blog.csdn.net/chaijunkun/article/details/6987443
最近在开发的项目需要承受很高的并发量。综合各种情况,决定使用Apache+Tomcat+JK的方式实现负载均衡,并且作为一个统一的服务还要实现群集(同步Session)。
在网上找了很多资料,都是零零散散的,没有一个完整的过程。通过几天的努力,完成了从编译、部署到配置的整个过程,期间也遇到了一些问题。在接下来的文字中将这些过程记录下来,做个笔记同时也分享给大家。
为了重新演示整个过程,我新搭建了一个服务器,各项参数如下:
CPU:Intel Xeon 5506*2
内存:DDR3 4G*4
主机型号:Dell PowerEdge R710
操作系统:CentOS release 5.7 x86_64版
内核版本:2.6.18
gcc版本:4.1.2
g++版本:4.1.2
java版本:1.6.0_30
- [root@lxp2 ~]# cat /etc/redhat-release
- CentOS release 5.7 (Final)
- [root@lxp2 ~]# uname -a
- Linux ku6 2.6.18-274.18.1.el5 #1 SMP Thu Feb 9 12:45:44 EST 2012 x86_64 x86_64 x86_64 GNU/Linux
- [root@lxp2 ~]# gcc --version
- gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-54)
- Copyright (C) 2006 Free Software Foundation, Inc.
- This is free software; see the source for copying conditions. There is NO
- warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- [root@lxp2 ~]# g++ --version
- g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-54)
- Copyright (C) 2006 Free Software Foundation, Inc.
- This is free software; see the source for copying conditions. There is NO
- warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- [root@lxp2 ~]# java -version
- java version "1.6.0_30"
- Java(TM) SE Runtime Environment (build 1.6.0_30-b12)
- Java HotSpot(TM) 64-Bit Server VM (build 20.5-b03, mixed mode)
- [root@lxp2 ~]#
gcc、g++和java是必须的,如果运行上述命令提示command not found,则需要安装。具体安装方法这里不做介绍,请参阅相关文档。
接下来要准备的是apache服务器、tomcat服务器和JK连接器
1.下载apache服务器源码包
apache服务器官方没有发布编译好的linux二进制包,只能通过下载源代码,然后自己编译。因此需要先下载源码。
访问网址http://httpd.apache.org/download.cgi,可以看到apache服务器目前放出的版本信息,推荐使用稳定版的release。
然后选择Unix版源码:
2.下载tomcat服务器源码包
目前tomcat服务器个人还是觉得6.0比较稳定。7.0毕竟是新出的东西,需要一定的生产实践考验才能达到理想的状态。因此这里选择tomcat 6.0。
访问网址http://tomcat.apache.org/download-60.cgi,可以看到目前稳定的版本为6.0.33:
这里强烈建议下载tar.gz格式的压缩包。在Linux下,文件访问有着严格的权限限制。一个文件是否允许以二进制或者脚本的形式执行,完全取决于其是否拥有执行缺陷,这与Windows识别文件后缀名(.exe、.bat)的方式不同。zip格式的压缩包中是不保留文件的权限信息的,而tar.gz格式的压缩包是保存有文件的权限信息的。
3.下载JK连接器源码包
作为apache与tomcat连接的桥梁,JK连接器使用C语言编写,与apache紧密结合,作为模块装载到apache服务器中,通过配置实现与特定的tomcat服务器进行通信,从而实现负载均衡的功能。
访问网址http://tomcat.apache.org/download-connectors.cgi,可以找到最新最稳定的JK连接器版本:
这里还是推荐下载tar.gz格式的源码。原因同上。
4.解压
apache服务器、tomcat服务器和JK连接器都已经下载好了,如下图所示:
然后将这三个包都解压出来:
5.编译apache服务器
首先编译apache服务器。在编译之前需要执行其自带的检测配置脚本。对于不同发行版本的Linux,默认安装的库都有所差别,即便是同一个发行版本,由于用户安装软件的软件不同,也会导致系统内包含的库有所区别。因此apache作为开源服务器,在编译前需要了解系统的库安装情况,某些模块需要依赖于特定的库,如果这些库不存在,配置脚本将自动忽略这些库的编译。经过检测时候会生成合适的MakeFile文件。这里特别提醒一句,如果直接执行配置脚本,是不会编译额外的模块的,我们希望使用额外模块时,需要在运行配置脚本命令后加入参数,让其尽最大可能编译可用的库。关于这方面的介绍可以参阅我的另外一篇文章“Linux下编译apache服务器modules文件夹缺少模块(.so)的问题”(http://blog.csdn.net/chaijunkun/article/details/6977466)。下面进入apache服务器源码目录并执行配置脚本:
- [root@lxp2 Downloads]# cd httpd-2.2.21
- [root@lxp2 httpd-2.2.21]# ./configure --enable-so --enable-mods-shared=most --with-mpm=worker
加入--with-mpm=worker是修改apache服务器的工作模式。默认模式是prefork。prefork采用预派生子进程方式,用单独的子进程来处理 不同的请求,进程之间彼此独立。相对于prefork,worker是全新的支持多线程和多进程混合模型的MPM(多路处理模块)。由于使用线程来处理,所以可以处理相对海量的请求,而系统资源的开销要小于基于进程的服务器。但是,worker也使用了多进程,每个进程又生成多个线程,以获得基于进程服务器的稳定性。
如果配置过程中出现
- configure: error: Cannot use an external APR with the bundled APR-util
这样的错误信息,说明本机没有安装apr运行库,需要下载并安装。访问网址:http://apr.apache.org/download.cgi,下载apr和apr-util:
解压apr和apr-util
- [root@lxp2 Downloads]# tar -xf apr-1.4.5.tar.gz
- [root@lxp2 Downloads]# tar -xf apr-util-1.3.12.tar.gz
进入apr,并编译
- [root@lxp2 Downloads]# cd apr-1.4.5
- [root@lxp2 apr-1.4.5]# ls
- apr-config.in build.conf helpers memory shmem
- apr.dep build-outputs.mk include misc strings
- apr.dsp CHANGES libapr.dep mmap support
- apr.dsw config.layout libapr.dsp network_io tables
- apr.mak configure libapr.mak NOTICE test
- apr.pc.in configure.in libapr.rc NWGNUmakefile threadproc
- apr.spec docs LICENSE passwd time
- atomic dso locks poll user
- build emacs-mode Makefile.in random
- buildconf file_io Makefile.win README
- [root@lxp2 apr-1.4.5]# ./configure
生成了MakeFile后直接编译
- [root@lxp2 apr-1.4.5]# ls
- apr-1-config buildconf dso locks poll
- apr-config.in build.conf emacs-mode Makefile random
- apr.dep build-outputs.mk file_io Makefile.in README
- apr.dsp CHANGES helpers Makefile.win shmem
- apr.dsw config.layout include memory strings
- apr.mak config.log libapr.dep misc support
- apr.pc config.nice libapr.dsp mmap tables
- apr.pc.in config.status libapr.mak network_io test
- apr.spec configure libapr.rc NOTICE threadproc
- atomic configure.in libtool NWGNUmakefile time
- build docs LICENSE passwd user
- [root@lxp2 apr-1.4.5]# make
编译好之后使用root权限安装:
- [root@lxp2 apr-1.4.5]# sudo make install
然后使用类似的方法配置apr-util:
- [root@lxp2 Downloads]# cd apr-util-1.3.12
- [root@lxp2 apr-util-1.3.12]# ./configure --with-apr=/usr/local/apr
编译apr-util:
- [root@lxp2 apr-util-1.3.12]# make
编译好之后使用root权限安装:
- [root@lxp2 apr-util-1.3.12]# sudo make install
当然如果你在配置apache服务器编译的时候没有提示缺少“APR”,请忽略上面关于APR编译的几步。
回到apache服务器源码所在目录,开始编译:
- [root@lxp2 httpd-2.2.21]# make
编译过程大概不到十分钟,完成之后使用root权限进行安装
- [root@lxp2 httpd-2.2.21]# sudo make install
如果不出意外,至此apache就安装成功了。来测试一下:
进入apache服务器的bin目录,并启动服务器:
- [root@lxp2 httpd-2.2.21]# cd /usr/local/apache2/bin/
- [root@lxp2 bin]# sudo ./apachectl start
- httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
在本地打开浏览器,访问http://127.0.0.1
如果出现“It Works!”则表示启动成功了
这里要注意一点就是Linux的防火墙问题。如果你的Linux服务器启动了防火墙,本地访问上面的网址是没有问题的,但如果其它计算机访问你的服务器有可能会连接失败。
出现这种情况的原因是防火墙将入站80端口封锁了。解决方法是将80端口加入到允许列表中:
进入防火墙设置后,如果发现Firewall状态为Enabled,表示防火墙已启用,需要将WWW(HTTP)服务标记为信任,如果需要使用hhtps协议,还要将Secure WWW(HTTPS)服务也标记为信任。如下图所示:
另外,此时如果有其他程序占用80端口也是会影响到apache服务器的,需要确保这个端口没有被占用。
还有我还要补充一点,在Mac OS中按照上述方法安装apache服务器是不行的。开始的时候我不想搭建Linux服务器,想到Mac OS也是类Unix的系统,操作命令什么的都一样,就先在Mac上实验了。结果安装上apache服务器后启动了,每次访问都提示505错误,service temporarily unavailable。经过查阅很多资料和尝试才发现,原来Mac系统中已经自带了apache服务器。具体应用是在“系统设置”中的“共享”功能。这个功能里有“Web共享”方式。其实现时使用的服务器就是apache。它采用的配置文件在/etc/httpd/目录中。这里的配置文件和自己安装的apache服务器配置文件冲突了,因此造成505错误。这一点需要注意。(注:我是用的Mac系统为Mac OS X Lion 10.7.2)
2011年11月23日补充:
如果你希望把apache服务器注册为系统服务,让它随着系统启动而启动,则需要在/etc/init.d/目录中建立服务管理脚本,我们将其命名为httpd:
- #!/bin/bash
- #chkconfig: 345 61 61
- #description: This is apache http service
- #processname: httpd
- pidfile="/usr/local/apache2/logs/httpd.pid"
- httpd_process_name="httpd"
- httpd_path="/usr/local/apache2/bin/apachectl"
- RETVAL=0
- start(){
- echo "Starting Apache Httpd Service..."
- httpd_pid_list=`pidof $httpd_process_name`
- if test -n "$httpd_pid_list"
- then
- echo "Fail To Launch Httpd, Since It Has Already Started"
- RETVAL=1
- else
- echo "Launching Apache Httpd Server"
- `$httpd_path "start"`
- RETVAL=$?
- echo "Launch Httpd Successfully"
- fi;
- }
- stop(){
- echo "Stopping Apache Httpd Service..."
- httpd_pid_list=`pidof $httpd_process_name`
- if test -n "$httpd_pid_list"
- then
- echo "Find Httpd Process, Start To End Them"
- `$httpd_path "stop"`
- if test "$?" = "0"
- then
- echo "Success to Terminate Httpd Service"
- RETVAL=0
- else
- echo "Can Not Terminate Httpd Service"
- RETVAL=1
- fi;
- else
- echo "Can Not Find Any Httpd Process, Fail To Stop Service"
- RETVAL=0
- fi;
- }
- restart(){
- stop
- if test "$?"="0"
- then
- #sleep 3 seconds to wait for process exit
- sleep 3
- start
- RETVAL= $?
- else
- RETVAL= $?
- fi;
- }
- status(){
- if test -f $pidfile
- then
- pid_list=`cat $pidfile`
- echo "$httpd_process_name (pid:$pid_list) is running"
- else
- echo "$httpd_process_name is stopped"
- fi;
- }
- case "$1" in
- start)
- start
- RETVAL=$?
- ;;
- stop)
- stop
- RETVAL=$?
- ;;
- restart)
- restart
- RETVAL=$?
- ;;
- status)
- status
- ;;
- *)
- echo {1}quot;Usage:$0 {start|stop|restart} asdfasdfasdfasdf "
- RETVAL=2
- esac
- exit $RETVAL
编写完成后保存并赋予755权限。然后在该目录下执行
- [root@lxp2 init.d]# chkconfig --add httpd
将服务添加到系统。脚本的具体解释请参阅我的另外一篇博文:
Linux中将memcached注册为系统服务(地址:http://blog.csdn.net/chaijunkun/article/details/7000600)。
6.编译JK连接器
刚刚完成了apache服务器的编译,接下来顺便把JK连接器也编译出来。
进入刚刚解压出来的tomcat-connector目录,再进入native目录。执行配置:
- [root@lxp2 Downloads]# cd tomcat-connectors-1.2.32-src
- [root@lxp2 tomcat-connectors-1.2.32-src]# ls
- BUILD.txt conf docs jkstatus LICENSE native NOTICE support tools xdocs
- [root@lxp2 tomcat-connectors-1.2.32-src]# cd native/
- [root@lxp2 native]# ls
- aclocal.m4 BUILDING.txt configure.in Makefile.am nt_service TODO.txt
- apache-1.3 CHANGES docs Makefile.in README.txt
- apache-2.0 common iis netscape scripts
- buildconf.sh configure jni NEWS STATUS.txt
- [root@lxp2 native]# ./configure --with-apxs=/usr/local/apache2/bin/apxs
这里需要注意的是配置脚本要添加一个apxs完整路径作为参数。apxs是一个为Apache HTTP服务器编译和安装扩展模块的工具,用于编译一个或多个源程序或目标代码文件为动态共享对象,使之可以用由mod_so提供的LoadModule指令在运行时加载到Apache服务器中。
另外,配置脚本运行时会检查g++所在的目录,如果没有安装g++,则会显示:
- configure: error: C++ preprocessor "/lib/cpp" fails sanity check
请检查是否已经正确安装了c++编译器。
因为实验用的服务器安装的是X86_64版的Red Hat Enterprise Linux Server ,因此要安装如下的包:
libstdc++-devel-4.1.2-46.el5.x86_64.rpm
gcc-c++-4.1.2-46.el5.x86_64.rpm
如果使用rpm命令无法安装,可以在http://szmov.net/centos5464/CentOS/里查找到相应的资源,下载下来安装也是一样的。
配置无误后就可以编译了,执行make命令:
- [root@lxp2 native]# make
7.JK连接器模块的部署
编译完成后使用ls命令来列出native目录下的所有目录和文件。注意有apache-1.3和apache-2.0两个目录。由于在配置编译的时候指定了apxs工具的位置。配置脚本会根据apxs的反馈结果自动识别目标apache服务器为2.x版本,因此本次编译生成的mod_jk.so模块会放在apache-2.0目录中,apache-1.3目录中是没有mod_jk.so的,这一点请注意。如下所示:
- [root@lxp2 native]# ls
- aclocal.m4 CHANGES configure libtool NEWS TODO.txt
- apache-1.3 common configure.in Makefile nt_service
- apache-2.0 config.log docs Makefile.am README.txt
- buildconf.sh config.nice iis Makefile.in scripts
- BUILDING.txt config.status jni netscape STATUS.txt
- [root@lxp2 native]# cd apache-2.0/
- [root@lxp2 apache-2.0]# ls
- bldjk54.qclsrc Makefile.apxs mod_jk.a mod_jk.lo
- bldjk.qclsrc Makefile.apxs.in mod_jk.c mod_jk.o
- config.m4 Makefile.in mod_jk.dsp mod_jk.so
- Makefile Makefile.vc mod_jk.la NWGNUmakefile
- [root@lxp2 apache-2.0]#
我们现在将编译好的mod_jk.so拷贝到apache服务器的modules目录中,这个目录是专门用来存放扩展模块的:
- [root@lxp2 apache-2.0]# sudo cp ./mod_jk.so /usr/local/apache2/modules/
- [root@lxp2 apache-2.0]# cd /usr/local/apache2/modules/
- [root@lxp2 modules]# ls
- httpd.exp mod_authz_user.so mod_include.so
- mod_actions.so mod_autoindex.so mod_info.so
- mod_alias.so mod_cgi.so mod_jk.so
- mod_asis.so mod_dav_fs.so mod_log_config.so
- mod_auth_basic.so mod_dav.so mod_logio.so
- mod_auth_digest.so mod_dbd.so mod_mime.so
- mod_authn_anon.so mod_deflate.so mod_negotiation.so
- mod_authn_dbd.so mod_dir.so mod_reqtimeout.so
- mod_authn_dbm.so mod_dumpio.so mod_rewrite.so
- mod_authn_default.so mod_env.so mod_setenvif.so
- mod_authn_file.so mod_expires.so mod_speling.so
- mod_authz_dbm.so mod_ext_filter.so mod_status.so
- mod_authz_default.so mod_filter.so mod_substitute.so
- mod_authz_groupfile.so mod_headers.so mod_userdir.so
- mod_authz_host.so mod_ident.so mod_version.so
- mod_authz_owner.so mod_imagemap.so mod_vhost_alias.so
至此JK连接器模块就部署完成了,但是还需要配置,具体配置将在下文中详细描述。
8.部署tomcat服务器
由于要在本地开启两个tomcat服务器实例以模拟负载均衡+群集的效果,因此我们需要将之前解压出来的tomcat复制成两份,进入解压时的目录,重命名解压出来的原始目录为tomcat_server_1,然后复制此目录,副本目录名称为tomcat_server_2:
- [root@lxp2 ~]# cd Downloads/
- [root@lxp2 Downloads]# ls
- apache-tomcat-6.0.33 cpp
- apache-tomcat-6.0.33.tar httpd-2.2.21.tar
- apr-1.4.5 tomcat-connectors-1.2.32-src
- apr-1.4.5.tar.gz tomcat-connectors-1.2.32-src.tar
- apr-util-1.3.12
- apr-util-1.3.12.tar.gz
- [root@lxp2 Downloads]# mv apache-tomcat-6.0.33 tomcat_server_1
- [root@lxp2 Downloads]# cp -r tomcat_server_1 tomcat_server_2
- [root@lxp2 Downloads]# ls
- apache-tomcat-6.0.33.tar httpd-2.2.21.tar
- apr-1.4.5 tomcat-connectors-1.2.32-src
- apr-1.4.5.tar.gz tomcat-connectors-1.2.32-src.tar
- apr-util-1.3.12 tomcat_server_1
- apr-util-1.3.12.tar.gz tomcat_server_2
- httpd-2.2.21
- [root@lxp2 Downloads]#
现在测试tomcat_server_1是否能够正常工作。
将我实现写好的一个测试用例下载下来(测试用例基于Spring 3.0编写,已经打成war包),下载地址:http://download.csdn.net/detail/chaijunkun/3815798。下载得到的文件是TestProject.war。将此压缩包放入tomcat_server_1的webapps目录下。然后切换到tomcat_server_1的bin目录下,启动tomcat_server_1:
- [root@lxp2 bin]# ./startup.sh
- Using CATALINA_BASE: /root/Downloads/tomcat_server_1
- Using CATALINA_HOME: /root/Downloads/tomcat_server_1
- Using CATALINA_TMPDIR: /root/Downloads/tomcat_server_1/temp
- Using JRE_HOME: /usr/java/jdk1.6.0_27
- Using CLASSPATH: /root/Downloads/tomcat_server_1/bin/bootstrap.jar
然后在浏览器中访问http://127.0.0.1:8080/TestProject/showInfo.do,如果没什么意外会显示类似于下面的信息:
- This message is from Server, RealPath:
- /root/Downloads/tomcat_server_1/webapps/TestProject/
- Current Session Id:
- 471D55C942346EC7BB48D07D9437D57E
信息中显示了当前测试用例所在的路径以及当前会话的SessionId。
此处要注意的地方同测试apache服务器是否正常工作时是一样的,需要注意防火墙是否阻塞了tomcat服务器默认采用的8080端口,是否有其他程序占用此端口。
看到没什么问题,我们先吧tomcat_server_1关闭
- [root@lxp2 bin]# ./shutdown.sh
- Using CATALINA_BASE: /root/Downloads/tomcat_server_1
- Using CATALINA_HOME: /root/Downloads/tomcat_server_1
- Using CATALINA_TMPDIR: /root/Downloads/tomcat_server_1/temp
- Using JRE_HOME: /usr/java/jdk1.6.0_27
- Using CLASSPATH: /root/Downloads/tomcat_server_1/bin/bootstrap.jar
9.apache服务器的配置
apache服务器、tomcat服务器和JK连接器都部署完成并能正确执行后就可以开始配置了
用vi或者其它编辑器打开/usr/local/apache2/conf/httpd.conf文件(由于该文件权限属性为rw-r--r--,因此要想修改此文件需要root权限),这就是apache服务器的主配置文件了。
这里我推荐使用图形化的编辑器来编辑它。因为这个文件很多行,如果用文本模式的编辑器编辑个人感觉很繁琐。
在有很多LoadModule语句的地方,末尾追加一行
LoadModule jk_module modules/mod_jk.so
然后在写有<IfModule XXXX>的区域追加一行如下配置
<IfModule jk_module>
JkWorkersFile conf/workers.properties
JkMountFile conf/uriworkermap.properties
JkLogFile logs/mod_jk.log
JkLogLevel warn
</IfModule>
下面给出了一个我写的配置。注意配置中有注释的地方。“#”开头的行为注释行。已经去除了原有的配置中的多余注释。
- ServerRoot "/usr/local/apache2"
- Listen 80
- ServerName 0.0.0.0
- ServerAdmin chaijunkun@hotmail.com
- DocumentRoot "/usr/local/apache2/htdocs"
- LoadModule authn_file_module modules/mod_authn_file.so
- LoadModule authn_dbm_module modules/mod_authn_dbm.so
- LoadModule authn_anon_module modules/mod_authn_anon.so
- LoadModule authn_dbd_module modules/mod_authn_dbd.so
- LoadModule authn_default_module modules/mod_authn_default.so
- LoadModule authz_host_module modules/mod_authz_host.so
- LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
- LoadModule authz_user_module modules/mod_authz_user.so
- LoadModule authz_dbm_module modules/mod_authz_dbm.so
- LoadModule authz_owner_module modules/mod_authz_owner.so
- LoadModule authz_default_module modules/mod_authz_default.so
- LoadModule auth_basic_module modules/mod_auth_basic.so
- LoadModule auth_digest_module modules/mod_auth_digest.so
- LoadModule dbd_module modules/mod_dbd.so
- LoadModule dumpio_module modules/mod_dumpio.so
- LoadModule reqtimeout_module modules/mod_reqtimeout.so
- LoadModule ext_filter_module modules/mod_ext_filter.so
- LoadModule include_module modules/mod_include.so
- LoadModule filter_module modules/mod_filter.so
- LoadModule substitute_module modules/mod_substitute.so
- LoadModule deflate_module modules/mod_deflate.so
- LoadModule log_config_module modules/mod_log_config.so
- LoadModule logio_module modules/mod_logio.so
- LoadModule env_module modules/mod_env.so
- LoadModule expires_module modules/mod_expires.so
- LoadModule headers_module modules/mod_headers.so
- LoadModule ident_module modules/mod_ident.so
- LoadModule setenvif_module modules/mod_setenvif.so
- LoadModule version_module modules/mod_version.so
- LoadModule mime_module modules/mod_mime.so
- LoadModule dav_module modules/mod_dav.so
- LoadModule status_module modules/mod_status.so
- LoadModule autoindex_module modules/mod_autoindex.so
- LoadModule asis_module modules/mod_asis.so
- LoadModule info_module modules/mod_info.so
- LoadModule cgid_module modules/mod_cgid.so
- LoadModule dav_fs_module modules/mod_dav_fs.so
- LoadModule vhost_alias_module modules/mod_vhost_alias.so
- LoadModule negotiation_module modules/mod_negotiation.so
- LoadModule dir_module modules/mod_dir.so
- LoadModule imagemap_module modules/mod_imagemap.so
- LoadModule actions_module modules/mod_actions.so
- LoadModule speling_module modules/mod_speling.so
- LoadModule userdir_module modules/mod_userdir.so
- LoadModule alias_module modules/mod_alias.so
- LoadModule rewrite_module modules/mod_rewrite.so
- # Load JK Connector Module
- LoadModule jk_module modules/mod_jk.so
- <IfModule !mpm_netware_module>
- <IfModule !mpm_winnt_module>
- User daemon
- Group daemon
- </IfModule>
- </IfModule>
- <IfModule dir_module>
- DirectoryIndex index.html
- </IfModule>
- # Load Configure while Loading JK Connector Module
- <IfModule jk_module>
- JkWorkersFile conf/workers.properties
- JkMountFile conf/uriworkermap.properties
- JkLogFile logs/mod_jk.log
- JkLogLevel warn
- </IfModule>
- # Apache Server is working in worker mode
- <IfModule worker.c>
- StartServers 5
- ServerLimit 20
- ThreadLimit 200
- MaxClients 4000
- MinSpareThreads 25
- MaxSpareThreads 250
- ThreadsPerChild 200
- MaxRequestsPerChild 1000
- </IfModule>
- <FilesMatch "^\.ht">
- Order allow,deny
- Deny from all
- Satisfy All
- </FilesMatch>
- ErrorLog "logs/error_log"
- LogLevel warn
- <IfModule log_config_module>
- LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
- LogFormat "%h %l %u %t \"%r\" %>s %b" common
- <IfModule logio_module>
- LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
- </IfModule>
- CustomLog "logs/access_log" common
- </IfModule>
- <IfModule alias_module>
- ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/"
- </IfModule>
- <IfModule cgid_module>
- </IfModule>
- DefaultType text/plain
- <IfModule mime_module>
- TypesConfig "conf/mime.types"
- AddType application/x-compress .Z
- AddType application/x-gzip .gz .tgz
- </IfModule>
- <IfModule ssl_module>
- SSLRandomSeed startup builtin
- SSLRandomSeed connect builtin
- </IfModule>
- <Directory "/">
- Options FollowSymLinks
- Deny from all
- Order deny,allow
- AllowOverride None
- </Directory>
- <Directory "/usr/local/apache2/htdocs">
- Options FollowSymLinks Indexes
- Allow from all
- Order allow,deny
- AllowOverride None
- </Directory>
- <Directory "/usr/local/apache2/cgi-bin">
- Options None
- Allow from all
- Order allow,deny
- AllowOverride None
- </Directory>
LoadModule表示当apache服务启动时要加载模块 jk_module为模块的别名,后面跟的modules/mod_jk.so就是相对于apache服务器所在目录(/usr/local/apache2/)的模块文件名。
<IfModule jk_module>区域表示当apache服务器加载jk_module(在LoadModule指令中指定的模块别名)模块时所做的配置。
其中:
JkWorkersFile 指定负载均衡服务器的配置文件,文件名为相对于apache服务器所在目录的conf/workers.properties文件
JkMountFile 指定那些请求交由负载均衡服务器来处理,那些由apache服务器来处理,配置文件为相对于apache服务器所在目录的conf/uriworkermap.properties文件
JkLogFile 指定JK连接器的日志输出文件,文件为相对于apache服务器所在目录的logs/mod_jk.log文件
JkLogLevel 指定JK连接器输出日志的级别,级别为warn以上的日志将被输出到日志文件中,可选的值级别由低到高分别为:TRACE DEBUG INFO WARN ERROR FATAL
------------------------------------------------------------------------------------------------------------------------------------------------
<IfModule worker.c>区域表示当apache服务器以worker模式工作时使用的配置。
指令说明:
StartServers:设置服务器启动时建立的子进程数量。因为子进程数量动态的取决于负载的轻重,所有一般没有必要调整这个参数。
ServerLimit:服务器允许配置的进程数上限。只有在你需要将MaxClients和ThreadsPerChild设置成需要超过默认值16个子进程的时候才需要使用这个指令。不要将该指令的值设置的比MaxClients 和ThreadsPerChild需要的子进程数量高。修改此指令的值必须完全停止服务后再启动才能生效,以restart方式重启动将不会生效。
ThreadLimit:设置每个子进程可配置的线程数ThreadsPerChild上限,该指令的值应当和ThreadsPerChild可能达到的最大值保持一致。修改此指令的值必须完全停止服务后再启动才能生效,以restart方式重启动将不会生效。
MaxClients:用于伺服客户端请求的最大接入请求数量(最大线程数)。任何超过MaxClients限制的请求都将进入等候队列。默认值是"400",16 (ServerLimit)乘以25(ThreadsPerChild)的结果。因此要增加MaxClients的时候,你必须同时增加 ServerLimit的值。笔者建议将初始值设为(以Mb为单位的最大物理内存/2),然后根据负载情况进行动态调整。比如一台4G内存的机器,那么初始值就是4000/2=2000。
MinSpareThreads:最小空闲线程数,默认值是"75"。这个MPM将基于整个服务器监视空闲线程数。如果服务器中总的空闲线程数太少,子进程将产生新的空闲线程。
MaxSpareThreads:设置最大空闲线程数。默认值是"250"。这个MPM将基于整个服务器监视空闲线程数。如果服务器中总的空闲线程数太多,子进程将杀死多余的空闲线程。MaxSpareThreads的取值范围是有限制的。Apache将按照如下限制自动修正你设置的值:worker要求其大于等于 MinSpareThreads加上ThreadsPerChild的和。
ThreadsPerChild:每个子进程建立的线程数。默认值是25。子进程在启动时建立这些线程后就不再建立新的线程了。每个子进程所拥有的所有线程的总数要足够大,以便可以处理可能的请求高峰。
MaxRequestsPerChild:设置每个子进程在其生存期内允许伺服的最大请求数量。到达MaxRequestsPerChild的限制后,子进程将会结束。如果MaxRequestsPerChild为"0",子进程将永远不会结束。将MaxRequestsPerChild设置成非零值有两个好处:可以防止(偶然的)内存泄漏无限进行而耗尽内存;
给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。
如果设置为非零值,笔者建议设为10000-30000之间的一个值。
公式:
ThreadLimit >= ThreadsPerChild
MaxClients <= ServerLimit * ThreadsPerChild,并且MaxClients必须是ThreadsPerChild的倍数
MaxSpareThreads >= MinSpareThreads+ThreadsPerChild
------------------------------------------------------------------------------------------------------------------------------------------------
接下来配置上面提到的conf/workers.properties文件和conf/uriworkermap.properties文件:
进入apache服务器的conf目录
- [root@lxp2 ~]# cd /usr/local/apache2/conf/
建立workers.properties和uriworkermap.properties文件
下面给出我已经配置好的两个文件
- #
- # workers.properties
- #
- # list the workers by name
- worker.list=loadBalanceServers, jk_watcher
- # localhost server 1
- # ------------------------
- worker.s1.port=8109
- worker.s1.host=localhost
- worker.s1.type=ajp13
- worker.s1.lbfactor=10
- worker.s1.cachesize=5
- # localhost server 2
- # ------------------------
- worker.s2.port=8209
- worker.s2.host=localhost
- worker.s2.type=ajp13
- worker.s2.lbfactor=10
- worker.s2.cachesize=5
- worker.loadBalanceServers.type=lb
- worker.loadBalanceServers.balanced_workers=s1,s2
- worker.loadBalanceServers.sticky_session=false
- worker.jk_watcher.type=status
- # worker.jk_watcher.read_only=True
- worker.jk_watcher.mount=/admin/jk
- worker.retries=3
worker.list 首先配置了两个worker,一个用于负载均衡,一个用于监视负载均衡状态。别名分别为loadBalanceServers和jk_watcher
然后分别配置位于本机的两个负载均衡服务器
worker.s1.port:第一台负载均衡服务器AJP协议连接器的连接端口,这里配置为8109
worker.s1.host:第一台负载均衡服务器的主机名、域名或者IP地址,这里配置为本机localhost
worker.s1.type:JK模块实现负载均衡采用的是AJP协议1.3版本,因此第一台负载均衡服务器的类型配置为ajp13
worker.s1.lbfactor:第一台负载均衡服务器在整个负载均衡系统中所占的权重,这里配置为10,权重越大,越有可能处理更多的请求,建议给性能好的机器配置更高的权重。
worker.s1.cachesize:apache服务器是多线程的,tomcat能够利用这一优势来维持一定数量的连接作为缓存。根据用户的多少来配置一个合适缓存连接数量有助于提高性能。这里配置为5
2013年7月8日补充:最近配置的这台单击集群出现了问题,在高并发量的情况下经常会报HTTP 503错误,这里我在每个worker上配置了如下参数:
- worker.s1.connection_pool_size=800
- worker.s1.connection_pool_minsize=25
- worker.s1.connection_pool_timeout=600
同样的配置也为s2增加了一份。这样JK组件和tomcat之间的连接池数量就增加了。另外为了应付大并发量下linux文件句柄不够用的情况,还需要配置ulimit -n
我这里配置的是65535。
s1是第一台负载均衡服务器的别名,这个别名要牢记,因为在接下来的配置中还会用到。
s2作为第二台负载均衡服务器,配置与s1大致相同。区别是AJP协议连接器的连接端口与s1的不同,这是因为要在同一台物理机上部署两个tomcat服务器的缘故。如果是两台物理机,则可以配置相同的端口,那么host属性就应该不一样了。两个tomcat服务器的权重都是10,则两个tomcat服务器将会有相同的处理请求的机会。
worker.loadBalanceServers.type:设置名称为“loadBalanceServers”的worker类型,这里配置为lb,也就是Load Balance负载均衡
worker.loadBalanceServers.balanced_workers:设置名称为“loadBalanceServers”的worker拥有哪些负责负载均衡的服务器实例,这里配置为s1和s2
worker.loadBalanceServers.sticky_session:设置负载均衡是否采用粘性会话。如果该属性设置为true,假设一个请求被s1处理了,下次来源于同一个客户端的请求也将被s1处理。直到s1已经达到最大连接数,JK才会将会话切换到其他服务器上。但是如果恰巧一直负责处理该会话的服务器down掉了,则会话将会丢失,明显的故障现象就是关于session的操作会出现莫名其妙的错误(例如你所运行的应用中用户可能已经登录了,但突然在一次访问后莫名其妙地提示没有登录)。这里配置为false,不启用粘性会话,让服务器都有机会处理请求,提高了系统的稳定性。
worker.jk_watcher.type:设置名称为“jk_watcher”的worker类型,这里配置为status,用于监视各个负载均衡服务器实例的运行状态
# worker.jk_watcher.read_only:设置名称为“jk_watcher”的worker是否为只读。上面已经将这个worker设置为了监控worker,如果设置为只读,就不能对负载均衡服务器参数进行配置了,这里先将这条配置注释掉,默认值为false,表示可以配置参数。
worker.jk_watcher.mount:设置名称为“jk_watcher”的worker(负载均衡服务器实例监视器)的挂载路径,这里配置为/admin/jk。这样就可以通过http://127.0.0.1/admin/jk来访问监视工具了,可以很方便地看到各个负载均衡服务器的工作情况。
worker.retries:这是worker全局的重试次数。在apache服务器启动后,会最多尝试若干次去连接这些负载均衡服务器,若连接不上就认为是down掉了,这里配置为3
下面给出配置,其作用是告诉apache服务器哪些请求由负载均衡服务器处理:
- #
- # uriworkermap.properties
- #
- #define all requests will be submitted to load balance servers
- #if the condition is satisfied, the filter will validate the next statement until it's not.
- #notice the order of the following statements
- /*=loadBalanceServers
- /jkstatus=jk_watcher
- !/*.gif=loadBalanceServers
- !/*.jpg=loadBalanceServers
- !/*.tif=loadBalanceServers
- !/*.png=loadBalanceServers
在配置文件中,以“!”开头的条件表示“不要”,“=”表示交给。
因此条件“/*=loadBalanceServers”表示将任何请求交给负载均衡服务器。
条件“!/*.jpg=loadBalanceServers”表示不要将.jpg结尾的请求交给负载均衡服务器
apache服务器接收到一个请求后会按照配置文件中的约束条件一个一个地检查,然后按照最后满足的匹配条件来决定由哪个worker来处理请求。
我的测试用例中需要输入http://127.0.0.1/TestProject/showInfo.do来查看信息。那么接下来就将这个请求作为示例来解释上面配置文件的工作过程:
经过上面的条件筛选,最符合条件的就是“/*=loadBalanceServers”。因此将请求转给了负载均衡服务器。
试想一下,如果在apache主目录下放置了一个名为a.jpg的图片,访问路径为http://127.0.0.1/a.jpg,请求经过该配置的检查,最后满足的条件就是“!/*.jpg=loadBalanceServers”,不要将.jpg结尾的请求交给负载均衡服务器,因此apache服务自己处理了该请求。
.jpg是静态数据,apache由C语言实现,直接针对系统底层进行IO操作,因此静态性能优良。而tomcat作为Servlet容器,擅长的是J2EE相关业务的解析。因此通过这样配置可以实现应用的“动静态分离”,相互取长补短,优化了性能。类似地也可以将.js、.css和.html等等静态文件按照上述格式填写到uriworkermap.properties配置文件中。
10.tomcat服务器的配置
由于在同一台物理机中部署了两个tomcat服务器实例,因此需要对端口相关的设置特别小心。tomcat服务器的主配置文件server.xml位于conf目录内。为了配置简单,我将最原始server.xml配置文件中的所有注释删除,然后配置好了一个模板,该模板是s1((即tomcat_server_1)的配置文件,如下所示:
- <?xml version='1.0' encoding='utf-8'?>
- <!--指定tomcat服务器的Telnet登录端口 并设置关闭服务器指令为"SHUTDOWN" 此处需注意服务器安全 -->
- <Server port="8005" shutdown="SHUTDOWN">
- <Listener className="org.apache.catalina.core.AprLifecycleListener"
- SSLEngine="on" />
- <Listener className="org.apache.catalina.core.JasperListener" />
- <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
- <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
- <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
- <GlobalNamingResources>
- <Resource name="UserDatabase" auth="Container"
- type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved"
- factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
- pathname="conf/tomcat-users.xml" />
- </GlobalNamingResources>
- <Service name="Catalina">
- <!-- HTTP服务端口 若在同一台机器上运行两个Tomcat实例 需要修改这个端口 具体数值无要求 不重复即可 -->
- <Connector port="8081" protocol="HTTP/1.1"
- connectionTimeout="20000" redirectPort="8443" />
- <!-- 此处的端口要与workers.properties文件中s1负载均衡服务器一致 -->
- <Connector port="8109" protocol="AJP/1.3" redirectPort="8443" />
- <!-- jvmRoute属性用来负载均衡的转发对象 值一定要与在workers.properties文件中指定的另外一台一样 -->
- <!-- 本实验中有两个tomcat服务器实例,因此s1服务器指向的转发对象为s2,s2服务器的这个地方要设置为s1 -->
- <!-- 如果有三个tomcat服务器实例做负载均衡,需要设置为s1->s2, s2->s3, s3->s1 -->
- <Engine name="Catalina" defaultHost="localhost" jvmRoute="s2">
- <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
- resourceName="UserDatabase" />
- <Host name="localhost" appBase="webapps" unpackWARs="true"
- autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
- <!-- 开始配置集群 -->
- <!-- 如果仅配置负载均衡,只需要将Cluster标签注释掉 -->
- <!-- 如果使用群集,应用的web.xml要加上distributable标签 -->
- <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" />
- <!-- 在群集中 本服务器用于接收来自其他服务器分发的信息 例如同步会话 -->
- <!-- 若在同一台机器上运行两个Tomcat实例 需要修改这个端口 具体数值无要求 不重复即可 -->
- <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
- address="auto" port="4001" 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>
- <!-- 结束配置群集 -->
- </Host>
- </Engine>
- </Service>
- </Server>
配置好s1服务器后再配置s2服务器。按照上面模板中的注释要求,修改相应的端口就可以了。PS:<Cluster ...></Cluster>节点之间部分不必自己动手敲进去,在tomcat服务器目录的/webapps/docs/cluster-howto.html文件中有这一段文字,拷贝出来贴到server.xml文件中即可。
2013年7月8日补充:
当大并发量存在时,即便Apache的JK组件与tomcat保持足够多数量的连接,也不能有效避免HTTP 503错误,因为在大量的请求被转发到tomcat时,tomcat无法相应那么多请求,于是抛出了503。需要在Connector的地方配置maxThreads参数,将最大线程数调大。如下所示:
- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" maxThreads="1000" URIEncoding="UTF-8" />
另外,如果业务代码中有频繁的SQL操作,还需要增加连接池的最大连接数,并控制好连接空闲释放连接的时间,因为如果时间太长,连接得不到释放,数据库连接会变得越来越多越来越多,直至连管理都登不上去。因为这个不在本文讨论范围之内,所以调整数据库连接池大小请参阅其他文档。
2012年1月16日补充:
tomcat6中,单机开发时为了保证GET请求参数采用UTF8编码(用于支持中文参数),在server.xml中会进行了如下设置:
<Connector port="8080" maxThreads="150" minSpareThreads="25"
maxSpareThreads="75" enableLookups="false" redirectPort="8443"
acceptCount="100" debug="99" connectionTimeout="20000"
disableUploadTimeout="true" URIEncoding="UTF-8" />
但是,当使用apache + tomcat 组成群集与负载均衡系统时,apache会将servlet/jsp请求转发给Tomcat。此时是通过AJP协议来转发的,因此对应的请求实际上是被转发到Tomcat监听的AJP端口上的,所以这里针对8080的设置自然就无效了。正确的方法是进行下面的设置:
<Connector port="8009" enableLookups="false" redirectPort="8443"
debug="0" protocol="AJP/1.3" URIEncoding="UTF-8" />
需要在群集环境中修改默认URL编码的朋友们在这里需要注意一下。
11.部署测试用例
将我提供的TestProject.war文件复制到两个tomcat服务器实例的webapps目录下,然后分别启动tomcat服务器,TestProject.war会自动部署上:
- [root@lxp2 Downloads]# cd tomcat_server_1/bin/
- [root@lxp2 bin]# ./startup.sh
- Using CATALINA_BASE: /root/Downloads/tomcat_server_1
- Using CATALINA_HOME: /root/Downloads/tomcat_server_1
- Using CATALINA_TMPDIR: /root/Downloads/tomcat_server_1/temp
- Using JRE_HOME: /usr/java/jdk1.6.0_27
- Using CLASSPATH: /root/Downloads/tomcat_server_1/bin/bootstrap.jar
- [root@lxp2 bin]# cd ../../
- [root@lxp2 Downloads]# cd tomcat_server_2/bin/
- [root@lxp2 bin]# ./startup.sh
- Using CATALINA_BASE: /root/Downloads/tomcat_server_2
- Using CATALINA_HOME: /root/Downloads/tomcat_server_2
- Using CATALINA_TMPDIR: /root/Downloads/tomcat_server_2/temp
- Using JRE_HOME: /usr/java/jdk1.6.0_27
- Using CLASSPATH: /root/Downloads/tomcat_server_2/bin/bootstrap.jar
- [root@lxp2 bin]#
这里需要注意的是两个tomcat服务实例的配置文件server.xml的访问权限。我这里使用的是root账户,所以不用太关心,但是如果用非root账户,一定要看看当前账户是否有server.xml的读写权限。如果没有,则tomcat服务器将不能成功启动。这种情况下要么修改server.xml的访问权限,要么使用root权限启动tomcat服务器。
- [root@lxp2 bin]# sudo ./startup.sh
2011年12月8日补充:最近刚刚发现tomcat的关闭脚本shutdown.sh有问题,经常不能完全回收资源。tomcat是基于Java编写的,当然其运行也就脱离不了java的JVM。当执行完shutdown.sh脚本后,tomcat服务器表面上是关闭了,然而JVM并没有完全退出,还在清理并回收资源,如果这个时候立即使用startup.sh进行启动,很容易导致再启动一个新的JVM实例,如果维护次数增多就会导致系统内存耗尽,我今天就经历了如下的错误:
registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped.
这条错误发现于logs目录下的catalina.日期.log文件中。无论再怎么启动tomcat都启动不了。后来重启了服务器居然可以启动了,后来同事说shutdown.sh脚本有问题。于是我经过实验,果然是这样。因此在这里奉劝读者,如果需要重新启动tomcat服务器,除了先执行shutdown.sh脚本外,还应该运行ps ax | grep java 来看看有没有残留的java进程,如果有,使用kill命令将其杀死,这才是正确的关闭tomcat服务器方法。
tomcat 6.0.25以后引入了内存泄露侦测,对于垃圾回收不能处理的对像,它就会做日志。
在tomcat的server.xml文件中,如下配置就是用来做内存泄露侦测的
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>;
也幸亏有了这个东西才提醒了我正在运行着多个JVM实例。
开启了tomcat服务器之后,就可以开启apache服务器了(注意,顺序很重要!一定要先开tomcat)
- [root@lxp2 ~]# cd /usr/local/apache2/bin/
- [root@lxp2 bin]# sudo ./apachectl start
- httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
- [root@lxp2 bin]#
这时候如果没问题,在本机浏览器访问http://127.0.0.1会出现如下页面:
然后输入网址访问http://127.0.0.1/TestProject/showInfo.do来看看效果:
然后再来刷新一下看看:
我们看到,访问URL没有改变,但是apache把两次访问的负载平均分配给了两个tomcat服务器实例,并且SessionId是相同的。
当再次刷新页面的时候,请求又再一次交给了s1服务器。这也正好验证了之前workers.properties文件中关于两服务器的权重设置。
至此,apache服务器+tomcat服务器+JK连接器实现负载均衡与群集的操作结束。
2012年7月2日补充:
有网友留言询问apache的httpd.conf文件是否要严格按照文中我的示例来写,另外还提出了关于session方面的疑问,我在这里一并写上。
首先关于httpd.conf配置文件,我提供的只是一个范本,其中一些用不到的选项是可以去掉的,比方说模块加载部分。如果有些模块根本用不到,那去除了之后会使得apache工作得更高效。具体模块对应的功能还要再参看其他资料。至于session的问题,其实涉及到开发技巧了。既然使用负载均衡和动静态分离,一般都是按照大网站的架构了,因此对于会话状态的管理也就需要做出变化。我建议通过加入memcache来实现。用户登录之后,服务器端生成唯一识别号(建议再用XXTEA算法加密一下)作为用户的Token和memcache里面的key,然后把用户对象作为value存放到memcache中,利用memcache自有的失效机制来实现session功能,再加上memcache本身支持集群,多少session都能管理得过来。凡是用到session的地方就改成凭借用户Token从memcache中取出用户对象(这套东西还是写成Util类比较好)。至于用户Token你怎么得到,随你喜好。可以写在Cookie中,也可以写在页面的每一个链接中(你可以看一下网易163、126的邮箱,登进去看访问地址就明白了),后者这样做的好处是浏览器可以禁用Cookie,对于这样的用户,在每一个URL中嵌入token=XXXXXX这样的参数就不会出现问题。
参考文献:
httpd.conf (4) 详解,http://hi.baidu.com/prince_zyb/blog/item/685b0901939db70f1c958307.html
Pro Apache Tomcat 6, Matthew Moodie, Kunal Mittal著,Apress公司出品。
ISBN-13 (pbk): 978-1-59059-785-9
ISBN-10 (pbk): 1-59059-785-0
相关推荐
Linux+Apache+Tomcat 的整合是目前最常用的 web 服务器架构之一,本文档将详细介绍如何在 Red Hat Enterprise Linux 5.2 环境下安装和配置 Apache2.2.12、Tomcat6.0.20 和 JDK6u16,以实现一个完整的 JSP 环境。...
在Linux环境中,通过Apache HTTP服务器(简称Apache)搭建Tomcat集群是一种常见的高可用性和负载均衡配置方式。Apache作为反向代理服务器,可以将用户的请求分发到多个Tomcat实例上,从而实现应用服务的扩展和容错。...
本说明手册为了阐述Linux搭建Apache+Tomcat环境,并详细介绍Tomcat的集群和负载均衡配置而编写。届时介绍域名的绑定,Red Hat和Ubuntu中随系统自动启动个软件的配置方法。
基于Xen虚拟机实现Apache Tomcat集群搭建的知识点如下: 1. Xen虚拟机技术:Xen是一个开源的虚拟机监视器,允许用户在同一台物理主机上运行多个虚拟机,每个虚拟机可以运行不同的操作系统。Xen具有高性能和高扩展性...
总结来说,Apache Tomcat 8.5.56在Linux环境下提供了稳定、高效且功能丰富的Java Web应用平台。通过了解其特性、安装配置、应用部署、安全管理和性能优化,我们可以更好地利用这个工具来搭建和管理我们的Web服务。
本文将详细介绍如何在Linux环境中搭建Apache HTTP服务器、Tomcat应用服务器以及使用mod_jk模块实现负载均衡集群。这个集群配置可以有效地分发Web请求到多个Tomcat实例,提高服务的响应能力和可靠性。 首先,我们来...
在Linux环境下,Apache Tomcat提供了稳定且高效的Web服务。本文将深入探讨如何在Linux系统上安装和配置Apache Tomcat 5.5.28。 一、Linux环境准备 在开始安装Apache Tomcat之前,确保你的Linux系统已经安装了Java ...
总结,`apache-tomcat-7.0.70.tar.gz`是针对Linux的Tomcat版本,通过解压、配置和启动,可以在Linux环境中搭建一个Java Web应用服务器。了解如何管理和维护Tomcat对于任何从事Java Web开发的人来说都是至关重要的。
通过以上步骤,你可以在Linux环境下搭建起一个基于Apache和Tomcat的Web服务环境。这种方式不仅可以提高Web应用的性能,还可以增强其安全性。希望这篇指南能帮助你在实际工作中顺利完成部署任务。
总结来说,Apache Tomcat 8.5.98 Linux安装包是为Linux环境设计的Java Web应用服务器,支持JSP和Servlet,通过简单的安装和配置过程,可以快速搭建和运行Java Web应用。通过理解并熟练掌握上述知识点,开发者和系统...
通过以上步骤,你可以在Linux环境下成功搭建起JSP、Apache和Tomcat的开发环境,为后续部署Java Web应用程序打下坚实的基础。这不仅涉及到软件的下载、编译和安装,还需要对Apache和Tomcat的配置有深入的理解,确保...
本文将详细讲解如何使用Linux操作系统,结合Nginx反向代理服务器和Tomcat应用服务器来搭建一个集群环境,实现负载均衡和服务高可用性。这个过程涉及到的知识点包括Linux系统管理、Nginx配置、Tomcat集群设置以及源码...
提供的文档资料如《ApacheTomcat整合教程.pdf》和《BOXIN网站系统环境搭建APACHE+TOMCAT.pdf》将更深入地指导你完成具体步骤。在学习过程中,遇到问题可参考官方文档或社区资源,不断积累经验,提高技术水平。
在这个"apache-tomcat-9.0.22.tar.gz"压缩包中,包含的是Apache Tomcat 9.0.22版本的源代码和可执行文件,适用于在Linux服务器上搭建Web服务环境。 1. **Tomcat 9.0.22 版本介绍**: Apache Tomcat 9.0.22是9.0...
"Linux平台下搭建Apache+Tomcat服务器" Linux平台下搭建Apache+Tomcat服务器是指在Linux操作系统下安装和配置Apache和Tomcat服务器的过程,以便实现Web服务器的搭建和网站的发布。下面将详细讲解这个过程中涉及的...
Apache Tomcat是一款开源的Java Servlet容器,主要用于部署和运行Java Web应用程序。它是Apache软件基金会的一部分,遵循Apache许可证,提供...通过以上步骤,你可以顺利地在Linux上搭建并运行Apache Tomcat 9.0.38。
在linux系统中搭建一个apache+tomcat+mysql的环境,并在其上部署web应用
### Linux环境下Apache+Tomcat+JK集群配置详解 #### 一、集群基础知识 集群技术是提升系统服务能力和高可用性的关键技术之一。通过将多台独立的服务器组织成一个集群,可以实现故障无缝迁移,即当集群中某台服务器...
如何在linux服务器上同时搭建php运行环境(apache)和java运行环境(tomcat) 一台linux上同时运行php和java网站项目 一台linux上同时运行apache httpd和java tomcat