最近在 Linux 下成功整合了 Tomcat 和 Apache ,其中难免踩了各种坑,在这里记录下过程以便大家学习。
首先,为什么要整合 Tomcat 和 Apache 呢?网上有一大把博客详解,我就简洁概括:
Tomcat 是应用(Java)服务器,支持 JSP 和静态页面请求,Apache 是 Web 服务器,只支持静态页面请求,然而 Apache 响应静态页面性能比 Tomcat 强,因此由 Apache 负责响应静态页面以及转发动态页面请求给 Tomcat,Tomcat 只负责响应 JSP 等动态页面请求,这样整合减少了 Tomcat 的开销,实现负载均衡。
整个过程主要分为以下四个步骤,后面还会讲各种坑及解决办法(PS:我的服务器是阿里云 CentOS 6.08 x64)
- 配置 JDK 环境
- 安装 Tomcat
- 安装 Apache
- 整合 Tomcat 和 Apache
1. 配合 JDK 环境
配置 Java 环境首先需要卸载 Linux 发行版自带的 OpenJDK,改装 SunJDK
-
检查系统是否安装了 OpenJDK,输入
java -version
,如下提示表示安装了[root@iZwz9f32qxgaqekk0b2ovwZ ~]# java -version java version "1.6.0" OpenJDK Runtime Environment (build 1.6.0-b09) OpenJDK 64-Bit Server VM (build 1.6.0-b09, mixed mode)
-
查找名字包含 java 的程序命令
rpm -qa | grep java
[root@iZwz9f32qxgaqekk0b2ovwZ ~]# rpm -qa | grep java java-1.8.0-openjdk-headless-1.8.0.131-0.b11.el6_9.x86_64 tzdata-java-2017b-1.el6.noarch java-1.8.0-openjdk-1.8.0.131-0.b11.el6_9.x86_64
-
用
rpm -e --nodeps ***
卸载程序,将上面的两个 OpenJDK 卸载[root@iZwz9f32qxgaqekk0b2ovwZ ~]# rpm -e --nodeps java-1.8.0-openjdk-1.8.0.131-0.b11.el6_9.x86_64 [root@iZwz9f32qxgaqekk0b2ovwZ ~]# rpm -e --nodeps java-1.8.0-openjdk-headless-1.8.0.131-0.b11.el6_9.x86_64
记住:nodeps前面是两条横
-
卸载完成后再输入
java
,已无信息表示卸载成功[root@iZwz9f32qxgaqekk0b2ovwZ ~]# java -bash: /usr/bin/java: No such file or directory
-
开始来安装 SunJDK,下载最新版的 SunJDK,有两种安装方式:
- 一个是
.rpm
后缀,用rpm -ivh ***.rpm
命令安装,安装后不需要手动配置 Java 环境变量,会自动配置 - 另一种是
.tar.gz
后缀,用tar -zxvf ***.tar.gz
命令安装,需要手动配置环境变量
- 一个是
-
这里选择第二种方式安装,下载后的安装包放在了
/usr/local/src
,我这里的安装包名是:jdk-8u144-linux-x64.tar.gz,首先解压到目录/usr/local
下[root@iZwz9f32qxgaqekk0b2ovwZ src]# tar -zxvf jdk-8u144-linux-x64.tar.gz -C /usr/local
解压完成后可以看到
/usr/local/jdk1.8.0_144
文件夹 -
配置 Java 环境变量
-
用
vi
编辑文件/etc/profile
[root@iZwz9f32qxgaqekk0b2ovwZ /]# vi /etc/profile
-
点击键盘 i 进入编辑模式,在文件尾部添加如下代码,按 Esc 键后输入
:wq
保存退出export JAVA_HOME=/usr/local/jdk1.8.0_144 export JRE_HOME=/usr/local/jdk1.8.0_144/jre export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
截图如下
-
-
保存文件后重新加载
/etc/profile
文件,让配置在当前会话生效[root@iZwz9f32qxgaqekk0b2ovwZ /]# source /etc/profile
-
再次测试安装是否成功
[root@iZwz9f32qxgaqekk0b2ovwZ /]# java -version java version "1.8.0_144" Java(TM) SE Runtime Environment (build 1.8.0_144-b01) Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)
2. 安装 Tomcat
-
下载 http://tomcat.apache.org/download-80.cgi
下载 .tar.gz 后缀的安装包老规矩放在/usr/local/src
目录下,这里安装包 apache-tomcat-8.5.15.tar.gz,解压安装包到/usr/local
目录下[root@iZwz9f32qxgaqekk0b2ovwZ src]# tar -zxvf apache-tomcat-8.5.15.tar.gz -C /usr/local
-
得到 Tomcat 目录
/usr/local/apache-tomcat-8.5.15
,重命名为 tomcat8.5.15 (个人习惯)[root@iZwz9f32qxgaqekk0b2ovwZ src]# mv /usr/local/apache-tomcat-8.5.15 /usr/local/tomcat8.5.15
-
添加 Tomcat 环境变量,和配置 Java 环境一样用
vi
编辑文件/etc/profile
,在末尾添加如下代码export CATALINA_HOME=/usr/local/tomcat8.5.15
-
修改 Tomcat 端口为
8080
,用vi
编辑/usr/local/tomcat8.5.15/conf/server.xml
,修改Connector
节点下的port
属性为8080
:
-
启动 Tomcat
[root@iZwz9f32qxgaqekk0b2ovwZ /]# cd /usr/local/tomcat8.5.15/bin [root@iZwz9f32qxgaqekk0b2ovwZ bin]# ./startup.sh Using CATALINA_BASE: /usr/local/tomcat8.5.15 Using CATALINA_HOME: /usr/local/tomcat8.5.15 Using CATALINA_TMPDIR: /usr/local/tomcat8.5.15/temp Using JRE_HOME: /usr/local/jdk1.8.0_144/jre Using CLASSPATH: /usr/local/tomcat8.5.15/bin/bootstrap.jar:/usr/local/tomc at8.5.15/bin/tomcat-juli.jar Tomcat started.
-
用
curl
Http工具本地测试 Tomcat 是否能访问[root@iZwz9f32qxgaqekk0b2ovwZ bin]# curl localhost:8080
最后再用外网测试能否访问
ip:8080
,如果不能访问,请检查阿里云 ECS 实例的安全组(实例 > 本实例安全组 > 配置规则)是否允许8080
端口访问,没有的话请点击 “添加安全组规则” ,填写如下图配置
3. 安装 Apache
-
Apache 运行需要
apr apr-util
,下载地址 http://archive.apache.org/dist/apr/,我这里下载了apr-1.6.2.tar.gz
和apr-util-1.6.0.tar.gz
分别将
apr
、apr-util
两个安装包放在/usr/local/src
目录下-
解压到
/usr/local
目录下,后面编译 Apache 会用到[root@iZwz9f32qxgaqekk0b2ovwZ src]# tar -zxvf apr-1.6.2.tar.gz -C /usr/local [root@iZwz9f32qxgaqekk0b2ovwZ src]# tar -zxvf apr-util-1.6.0.tar.gz -C /usr/local
下载 Apache 资源包,地址 > http://httpd.apache.org/download.cgi,我这里下载最新版的,名为 Apache HTTP Server 2.4.27
-
还是老规矩,安装包放到
/usr/local/src
目录下,解压到/usr/local
目录下[root@iZwz9f32qxgaqekk0b2ovwZ ~]# cd /usr/local/src [root@iZwz9f32qxgaqekk0b2ovwZ src]# tar -zxvf httpd-2.4.27.tar.gz -C /usr/local
-
解压后进入文件夹 httpd-2.4.27,然后编译、安装Apache
[root@iZwz9f32qxgaqekk0b2ovwZ src]# cd ../httpd-2.4.27 [root@iZwz9f32qxgaqekk0b2ovwZ httpd-2.4.27]# ./configure --prefix=/usr/local/apache2 --enable-rewrite --enable-ssl --enable-module=so --sysconfdir=/etc/httpd --libdir=/usr/lib64 --with-included-apr [root@iZwz9f32qxgaqekk0b2ovwZ httpd-2.4.27]# make [root@iZwz9f32qxgaqekk0b2ovwZ httpd-2.4.27]# make install
- --prefix:指定安装目录
- --enable-rewrite:支持重写 URL
- --enable-ssl:启用 ssl 功能,如果不启用将无法使用 https
- --enable-module=so:支持动态共享模块
- --sysconfdir=/etc/httpd:指定 Apache 配置目录,如果没有指定该参数,配置会在 Apache 主目录下的
conf
文件夹里,这个参数会影响后面 Tomcat 与 Apache 的整合 - --with-included-apr:指定
apr
库文件,编译时会自动在srclib
目录下找,下面会讲到
-
问题来了,编译安装过程可能出现的错误如下:
提示错误
error: ‘apr_xml_parser’ has no member named ‘xp’
没有xml解析器,解决:yum install expat-devel
-
提示错误:
openssl version is too old
更新 openssl 版本:yum install openssl-devel yum update openssl
-
安装时提示:
make[2]: *** [htpasswd] Error 1 make[2]: Leaving directory `/usr/local/httpd-2.4.27/support' make[1]: *** [install-recursive] Error 1 make[1]: Leaving directory `/usr/local/httpd-2.4.27/support' make: *** [install-recursive] Error 1
编译配置中没有添加参数
--with-included-apr
,导致找不到相应的库文件,在configure
后面添加就行,不过网上还有其他解决办法:(我试了没用)# mv /usr/lib/libm.a /usr/lib/libm.a.bak # mv /usr/lib/libm.so /usr/lib/libm.so.bak # mv /usr/lib/libexpat.so /usr/lib/libexpat.so.bak # ln -s /usr/lib64/libm.a /usr/lib/libm.a # ln -s /usr/lib64/libm.so /usr/lib/libm.so # ln -s /usr/lib64/libexpat.so /usr/lib/libexpat.so
-
编译时添加了参数
--with-included-apr
后编译错误提示
configure: error: Bundled APR requested but not found at ./srclib/. Download and unpack the corresponding apr and apr-util packages to ./srclib/.
这是由于 Apache 编译需要apr apr-util
,而编译器找不到源代码文件,我们只需要把上面下载解压后的两个文件夹复制到/usr/local/httpd-2.4.27/srclib
目录下,再编译就没问题了[root@iZwz9f32qxgaqekk0b2ovwZ local]# cp -r apr-1.6.2 /usr/local/httpd-2.4.27/srclib/apr [root@iZwz9f32qxgaqekk0b2ovwZ local]# cp -r apr-util-1.6.0 /usr/local/httpd-2.4.27/srclib/apr-util
-
一切终于顺利了!可以开始启动 Apache
[root@iZwz9f32qxgaqekk0b2ovwZ ~]# cd /usr/local/apache2/bin // 启动 [root@iZwz9f32qxgaqekk0b2ovwZ bin]# ./apachectl start // 关闭 [root@iZwz9f32qxgaqekk0b2ovwZ bin]# ./apachectl stop // 重启 [root@iZwz9f32qxgaqekk0b2ovwZ bin]# ./apachectl restart
天呀,错误又来了,启动时候提示了以下异常:
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message
只要修改httpd.conf
文件中的ServerName
属性,去掉前面的注释#
号,并后面改为127.0.0.1:80
,再次启动终于没错误了最后,确保阿里云 ECS 安全组允许访问
80
端口,外网浏览器访问ip
,出现如下表示成功:
4. 整合 Tomcat 和 Apache
- 整合需要 tomcat-connectors 进行桥连接,下载 mod_jk
-
老规矩把安装包放在
/usr/local/src
目录下,解压文件 tomcat-connectors-1.2.42-src.tar.gz 到/usr/local
目录下,后进入native
目录下配置(configure)、编译(make)、安装(make install)[root@iZwz9f32qxgaqekk0b2ovwZ src]# tar -zxvf tomcat-connectors-1.2.42-src.tar.gz -C /usr/local/ [root@iZwz9f32qxgaqekk0b2ovwZ src]# cd .. [root@iZwz9f32qxgaqekk0b2ovwZ local]# cd tomcat-connectors-1.2.42-src/native/ [root@iZwz9f32qxgaqekk0b2ovwZ native]# ./configure --with-apxs=/usr/local/apache2/bin/apxs [root@iZwz9f32qxgaqekk0b2ovwZ native]# make [root@iZwz9f32qxgaqekk0b2ovwZ native]# make install
-
编译安装后在
native/apache-2.0
目录下会生成了mod_jk.so
文件,把它复制到 Apache 目录下的modules
目录里[root@iZwz9f32qxgaqekk0b2ovwZ native]# cp apache-2.0/mod_jk.so /usr/local/apache2/modules/
-
创建相关配置文件,由于安装 Apache 配置时指定了其配置文件的目录在
/etc/httpd
,进入/etc/httpd
,创建两个文件:mod_jk.conf
和workers.properties
,分别写入如下内容:
mod_jk.conf:#LoadModule jk_module modules/mod_jk.so JkWorkersFile /etc/httpd/workers.properties # Where to put jk logs JkLogFile /etc/httpd/logs/mod_jk.log # Set the jk log level [debug/error/info] JkLogLevel info # Select the log format JkLogStampFormat "[%a %b %d %H:%M:%S %Y]" # JkOptions indicate to send SSL KEY SIZE, JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories # JkRequestLogFormat set the request format JkRequestLogFormat "%w %V %T" JkMount /*/servlet/* worker1 JkMount /*.jsp worker1 JkMount /application/* worker1 JkMount /*.do worker1 JkMount /*.class worker1 JkMount /*.jar worker1
workers.properties:
# Defining a worker named worker1 and of type ajp13 worker.list=worker1 # Set properties for worker1 worker.worker1.type=ajp13 worker.worker1.host=localhost worker.worker1.port=8009 worker.worker1.lbfactor=50 worker.worker1.cachesize=10 worker.worker1.cache_timeout=600 worker.worker1.socket_keepalive=1 worker.worker1.socket_timeout=300
-
完成前面准备工作后,接着加载 mod_jk 模块和导入 mod_jk 配置只需对
/etc/httpd/httpd.conf
文件添加如下内容:LoadModule jk_module modules/mod_jk.so Include /etc/httpd/mod_jk.conf
接下来重启 Apache,使用命令
# ./apachectl restart
,如果重启失败,可以打开错误日志文件
/usr/local/apache2/logs/error_log
,如果看到如下信息:
[Thu Aug 31 10:29:48.568384 2017] [jk:error] [pid 25649:tid 140007198447360] (2)No such file or directory: mod_jk: could not open JkLog file /etc/httpd/logs/mod_jk.log
AH00016: Configuration Failed
是因为我们没有创建/etc/httpd/logs/mod_jk.log
文件,只要用touch
命令手动创建该文件就行了。测试整合是否成功。
在/usr/local/tomcat8.5.15/webapps/ROOT
创建test.jsp
文件,写入tomcat test jsp
内容,用外网浏览器访问ip/test.jsp
,出现以下内容表示成功!