最近在 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
image.png
下載 .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
:
Paste_Image.png -
啟動 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
,出現以下內容表示成功!