[iyunv@lxp2 ~]# cat /etc/redhat-release
CentOS release 5.7 (Final)
[iyunv@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
[iyunv@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.
[iyunv@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.
[iyunv@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)
[iyunv@lxp2 ~]#
gcc、g++和java是必须的,如果运行上述命令提示command not found,则需要安装。具体安装方法这里不做介绍,请参阅相关文档。
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
[iyunv@lxp2 Downloads]# tar -xf apr-1.4.5.tar.gz
[iyunv@lxp2 Downloads]# tar -xf apr-util-1.3.12.tar.gz
进入apr,并编译
[iyunv@lxp2 Downloads]# cd apr-1.4.5
[iyunv@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
[iyunv@lxp2 apr-1.4.5]# ./configure
生成了MakeFile后直接编译
[iyunv@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
[iyunv@lxp2 apr-1.4.5]# make
编译好之后使用root权限安装:
[iyunv@lxp2 apr-1.4.5]# sudo make install
然后使用类似的方法配置apr-util:
[iyunv@lxp2 Downloads]# cd apr-util-1.3.12
[iyunv@lxp2 apr-util-1.3.12]# ./configure --with-apr=/usr/local/apr编译apr-util:[iyunv@lxp2 apr-util-1.3.12]# make
编译好之后使用root权限安装:
[iyunv@lxp2 apr-util-1.3.12]# sudo make install
当然如果你在配置apache服务器编译的时候没有提示缺少“APR”,请忽略上面关于APR编译的几步。
回到apache服务器源码所在目录,开始编译:
[iyunv@lxp2 httpd-2.2.21]# make
编译过程大概不到十分钟,完成之后使用root权限进行安装
[iyunv@lxp2 httpd-2.2.21]# sudo make install
如果不出意外,至此apache就安装成功了。来测试一下:
进入apache服务器的bin目录,并启动服务器:
[iyunv@lxp2 httpd-2.2.21]# cd /usr/local/apache2/bin/
[iyunv@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权限。然后在该目录下执行
[iyunv@lxp2 Downloads]# cd tomcat-connectors-1.2.32-src
[iyunv@lxp2 tomcat-connectors-1.2.32-src]# ls
BUILD.txt conf docs jkstatus LICENSE native NOTICE support tools xdocs
[iyunv@lxp2 tomcat-connectors-1.2.32-src]# cd native/
[iyunv@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
[iyunv@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命令:
[iyunv@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的,这一点请注意。如下所示:
[iyunv@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关闭
[iyunv@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>
#
# 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)的配置文件,如下所示:
[iyunv@lxp2 Downloads]# cd tomcat_server_1/bin/
[iyunv@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
[iyunv@lxp2 bin]# cd ../../
[iyunv@lxp2 Downloads]# cd tomcat_server_2/bin/
[iyunv@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
[iyunv@lxp2 bin]#
这里需要注意的是两个tomcat服务实例的配置文件server.xml的访问权限。我这里使用的是root账户,所以不用太关心,但是如果用非root账户,一定要看看当前账户是否有server.xml的读写权限。如果没有,则tomcat服务器将不能成功启动。这种情况下要么修改server.xml的访问权限,要么使用root权限启动tomcat服务器。
[iyunv@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-->