Apache 及 Tomcat 的结合

网页应用伺服器上,Apache 为众多伺服器的首选,对於 JSP 的服务来说当然是以 Tomcat 为主要的选择,在目前的主流上若要使用 JSP 开发 Web 网页程式的话, Apache 和 Tomcat 当然是最佳选择,在这里就由小弟介绍如何使用 Apache 配合 connector 来连结 Tomcat。

首先在一个重要的 Web 服务平台上,若打算要把 Apache 和 JSP 分开以分化流量并保护 JSP 程式的话,一般都会把 JSP 放在另一台跑 Tomcat 的主机上,而静态的 html 则是放在 Apache 上。JSP 程式主机若以安全原则来说是不应该放在别人看得到的公开网路上,最好是放在一个 Web Cluster 的内部环境里面,以下是这次范列的 Web Server 加构图。

我们的环境下,使用者连上我们的 http-fountain,而 java-garden是放在内部的网路里,Web 程式虽然是放在 java-garden 里,但使用却感觉不出来。

     +-------+
     | User  |
     +-------+
         | (Port 80)
     +-------+
     |  http | (http-fountain, eth0: 11.22.33.44, eth1: 192.168.1.86)
     +-------+
         | (Port 8009)
     +-------+
     |  JSP  | (java-garden, 192.168.1.87)
     +-------+

这样的设计有几点好处:程式和网页分开减少档案损坏的风险、JSP 应用伺服器较不会被外界攻击、可单一维护程式或网页、若日后流量大的话 Tomcat 可以做负载平衡。

以下我们就来看看如何建立这一个完整的环境。

设定 DNS:

DNS 应该不用说了吧,一定要先对完整才可以使用得当,请使用 host 工具来看看是否设定正确。在这个 Web Cluster 上内部应该要查得到 http-fountain 和 java-garden。

root # host http-fountain.l-penguin.idv.tw
http-fountain.l-penguin.idv.tw has address 192.168.1.86
root # host java-garden.l-penguin.idv.tw
java-garden.l-penguin.idv.tw has address 192.168.1.87

而外部的使用者应该只能查到 http-fountain 的公开 IP

root # host http-fountain.l-penguin.idv.tw
http-fountain.l-penguin.idv.tw has address 11.22.33.44

因为有内外部,所以你有可能需要使用到 Bind 9 的 View 功能,至於详细的使用方法请参考 bind - DNS 设定 (New window)

建立一个美好泡咖啡的花园 java-garden.l-penguin.idv.tw:

设定 Java 环境

首先你的机器应该有有 Java 环境这样 Tomcat 才可以顺利执行。你可以到 Sun 的下载区去下载最近版本的 Java JDK (http://java.sun.com/javase/downloads/index.jsp) 并且安装它。在这里我是下载可自解的二进制可执行档 (Linux self-extracting file)。

最后你可以发现下载后会是一个 .bin 档案,你可以附与它一个 x 可执行权限然后开始执行。

root # chmod +x jdk-1_5_0_07-linux-i586.bin
root # ./jdk-1_5_0_07-linux-i586.bin

解开之后会多出一个目录,我习惯把应用程式搬到 /usr/local 之下,而这个 Java 也不例外。

root # mv jdk1.5.0_07/ /usr/local/java

当然为了 Tomcat 的安装与执行,你并需设定 JAVA_HOME 这个环境变数,你可以设定在 /etc/profile 上。

root # echo 'JAVA_HOME=/usr/local/java' >> /etc/profile

如果你要马上生效的话,执行 export 把这个变数转成环境变数。

root # export JAVA_HOME=/usr/local/java
root # env | grep JAVA_HOME
JAVA_HOME=/usr/local/java
root #

设定 Tomcat 环境:

现在是重头戏 Tomcat 的表演时刻了,你可以到 http://tomcat.apache.org/ 下载最新版本的 Tomcat 来安装,当然我是下载 Tomcat 5.5 版本的 Tomcat 二进制可执行档。解开之后移到 /usr/local/tomcat5 目录。

root # wget http://apache.cdpa.nsysu.edu.tw/tomcat/tomcat-5/v5.5.17/bin/apache-tomcat-5.5.17.tar.gz
root # tar -zxvf apache-tomcat-5.5.17.tar.gz
root # mv apache-tomcat-5.5.17 /usr/local/tomcat5

尝试启动 Tomcat 并看看它的样子!

现在你已经把 Tomcat 装好,并且拥有 JAVA 环境了,你可以试著启动 Tomcat 来看看。

root # /usr/local/tomcat5/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat5
Using CATALINA_HOME: /usr/local/tomcat5
Using CATALINA_TMPDIR: /usr/local/tomcat5/temp
Using JRE_HOME: /usr/local/java
root #

好的,你可以看看 Tomcat 是使用那些 Port。

root # netstat -ntulp | grep java
tcp 0 0 ::ffff:127.0.0.1:8005 :::* LISTEN 2157/java
tcp 0 0 :::8009 :::* LISTEN 2157/java
tcp 0 0 :::8080 :::* LISTEN 2157/java
root #

由 netstat 可得知它是使用了 8080 和 8009,这个 8009 等一下是要由 mod_jk2 来使用的,而 8080 是 Tomcat 的 Web Service 服务,你可以在 Web Browser 输入 http://java-garden.l-penguin.idv.tw:8080/ 看看。

Tomcat Web Service

当然这个 java-garden 只有在内部才可看到,使用者是看不到的,若使用者看得到的话就失去了我故意安排 java-garden 在内部网的安全心意了。

以上就完成了 Tomcat 的设置,下面再来看看如何设定 Apache 并使用 mod_jk2 这个 connector 来连结 Apache 和 Tomcat。

建设 http 喷水池 http-fountain.l-penguin.idv.tw:

建立基本的 Apache

首先你要设定安装基本的 Apache,安装 Apache 你可以参考 LAMP (New window)文章有详细的安装过程,并不需要有额外的安装选项。

编译 mod_jk2 模组

在编译 mod_jk2 之前,我先来说明一下为什么要在众多的 connector 之中选择 mod_jk2。目前的连结器中主要有下面的几种:

而我使用下表来表示它们各自差异。

连结器
通讯协定
支援平衡负载
mod_jserv ajp 1.2 第一个 AJP 连结器,不支援负载平衡。
mod_jk ajp 1.3 支援负载平衡,但已不用。
mod_jk2 ajp 1.3 支援负载平衡。
mod_webapp warp 1.0 不支援负载平衡

现在来看看下面的编译过程。

当你安装完成 Apache 之后,还需要编绎 mod_jk2 这个连结器才可以该 Apache 和 Tomcat 相互沟通,以下我示范使用 mod_jk2 原始档来编译,你可以到 http://tomcat.apache.org/download-connectors.cgi 下载得到。

root # wget http://apache.cdpa.nsysu.edu.tw/tomcat/tomcat-connectors/jk2/jakarta-tomcat-connectors-jk2-src-current.tar.gz
root # tar -zxvf jakarta-tomcat-connectors-jk2-src-current.tar.gz

解开之后你会在同目录之下得到一个 jakarta-tomcat-connectors-jk2-2.0.4-src 的目录,接下来请依如下的顺序来编译。

root # cd jakarta-tomcat-connectors-jk2-2.0.4-src/
root # cd jk/native2/
root # ./configure --with-apxs2=/usr/local/httpd/bin/apxs --with-apache2=/usr/local/httpd/
root # make
root # cd ../build/jk2/apache2/

经过以上烦杂的动作之后,会得到一个叫做 mod_jk2.so 的 module,请把它复制到 apache 的 module 目录里。

root # cp mod_jk2.so /usr/local/httpd/modules/

设定 httpd.conf 及 mod_jk2 需要的设定档 (workers2.properties),同时建立 java-garden 的 JSP 连结

现在请编辑 httpd.conf 档案以便在 apache 启动时载入 mod_jk2 模组。

root # vi /usr/local/httpd/conf/httpd.conf
--------------------------------------------------------------
LoadModule jk2_module modules/mod_jk2.so
--------------------------------------------------------------

编辑 workers2.properties

root # vi /usr/local/httpd/conf/workers2.properties
--------------------------------------------------------------

[logger]
level=DEBUG

[config:]
file=/usr/local/httpd/conf/workers2.properties
debug=0
debugEnv=0

[shm:]
info=Scoreboard. Required for reconfiguration and status with multiprocess servers
file=/usr/local/httpd/logs/jk2.shm
size=1000000
debug=0
disabled=0

[workerEnv:]
info=Global server options
timing=1
debug=0

[channel.socket:java-garden.l-penguin.idv.tw:8009]
info=Ajp13 forwarding over socket
debug=0
tomcatId=java-garden.l-penguin.idv.tw:8009

[channel.jni:jni]
info=The jni channel, used if tomcat is started inprocess

[status:]
info=Status worker, displays runtime informations

[uri:/jkstatus/*]
info=Display status information and checks the config file for changes.
group=status:

[uri:/java-garden/*.jsp]
info=java-garden.
context=/java-garden
worker=ajp13:java-garden.l-penguin.idv.tw:8009
debug=0
--------------------------------------------------------------

以上在 workers2.properties 档里粗体字表示需要注意的地方,是要输入 Tomcat 主机的名称或是 IP。编辑好了以上的设定之后还不能完全启动,必需再为 Tomcat 设立 java-garden 的虚拟目录才行。

上面 [uri:/java-garden/*.jsp] 表示只有 .jsp 档案才会经由 mod_jk2 向 Tomcat 请求需要,一般的 html 或图片影像档就由本机的 http 主机负责传输就可以了。

在 Tomcat 上为 java-garden 建立虚拟目录

要编辑 Tomcat 的虚拟目录你需要看得懂 XML 语法,其实也跟 httpd.conf 差不多一样,而它的编辑档是在 ${TOMCAT_HOME}/conf/server.xml 之下,而目录是建在 <host> 和 </host> 之间。

现在请到你的 Tomcat 主机里执行编辑动作。

root # vi /usr/local/tomcat5/conf/server.xml
--------------------------------------------------------------
<Host>
~略~
<Context path="/java-garden"
docBase="/data/web/java-garden"
debug="0"
reloadable="true"
crossContext="true">
</Context>
</Host>
--------------------------------------------------------------

在 server.xml 文件文打粗体的表示要注意的地方,path 表示为 http 网址后的连结,docBase 表示真正所在的目录位置。

最终一回-实际验收

终於到了可以实际验收的阶段了,请记得只要你收改过设定档,就要重新启动 httpd 和 Tomcat 服务以重新读取设定档。

Tomcat 主机

root # /usr/local/tomcat5/bin/shutdown.sh
Using CATALINA_BASE: /usr/local/tomcat5
Using CATALINA_HOME: /usr/local/tomcat5
Using CATALINA_TMPDIR: /usr/local/tomcat5/temp
Using JRE_HOME: /usr/local/java
root # /usr/local/tomcat5/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat5
Using CATALINA_HOME: /usr/local/tomcat5
Using CATALINA_TMPDIR: /usr/local/tomcat5/temp
Using JRE_HOME: /usr/local/java
root #

Http 主机

root # /usr/local/httpd/bin/apachectl stop
root # /usr/local/httpd/bin/apachectl start

我在 Tomcat 主机上的 /data/web/java-garden 放了几只 jsp 文件,包含一个 index.html 档;而在 HTTP 主机上放了几个 html 文件,也包含了一个 index.html 档,现在来看看是否可以正常的执行。

若你要测试的话请在 Web Browser 输入 http://http-fountain.l-penguin.idv.tw/java-garden/index.jsp 看看有什么反应。

The example of java-garden, show the index.jsp.

再来看看 index.html 档。

The example of http-fountain, show the index.htm

好了,经过以上的实验,你可以发现其实 Apache 只有在要求 jsp 时才会向 Tomcat 主机要求回应,否则的话都是由 Web 主机本身回应。

参考文件

08/08/2006

首页