Apache 2.0
在我撰写本文时,Apache 2.0 稳定版本发布已经 लगभग一个月了——而且从我所了解的一切来看,它绝对已经准备好投入实际应用了。虽然还有其他开源 HTTP 服务器,但 Apache 绝对是最知名和支持最好的。世界上 60% 的网站都在使用 Apache,几乎每个 Linux 发行版都自带 Apache,甚至一些商业应用服务器也将其作为一部分。Zope 和 Jakarta-Tomcat 都有自己的内置 HTTP 服务器,但几乎没有人直接将这些服务器暴露给 Web。相反,他们使用 Apache 作为前端,因为它兼具性能和灵活性。本月,我们将更仔细地研究 Apache 2.0 [另请参阅“Apache 2.0:全新改进的 ‘A PatCHy’ 的内部机制”,网址为 www.linuxjournal.com/article/4559]。
如果您熟悉 Apache 1.x,那么 Apache 2.0 中的东西很少会让您感到惊讶。首先,Apache 继续保持高度模块化,允许您仅包含服务器中您认为必要的模块。但是,Apache 1.3 有一个包含基本 HTTP 实现的核心模块,而 Apache 2.0 甚至将更多受支持的协议委派给模块。这有很多优点,包括我们现在可以根据需要从 Apache 添加(和删除)协议。换句话说,Apache 现在已经成为通用互联网服务器,而不仅仅是 HTTP 服务器。有多少项目会利用此功能还有待观察。
Apache 从未打算成为地球上最快的服务器。相反,它的设计初衷是通过模块系统进行扩展。每个模块都提供不同的功能;有兴趣从其系统中榨取最后一丝性能的管理员不必包含不相关的模块。例如,如果我们知道我们的服务器永远不会运行任何 CGI 程序,那么我们可以轻松删除 mod_cgi,从而获得一些 CPU 周期和内存。
Apache 2.0 延续了 Apache 的长期传统,即在多个命名阶段处理每个 HTTP 事务。模块可以在这些阶段中的任何一个阶段检查或修改事务,方法是将自己的处理程序附加到适当的钩子。例如,mod_speling(它纠正 URL 中的大小写和拼写错误——名称是故意拼写错误的)将其处理程序附加到“fixup”阶段钩子,在服务器生成响应之前立即执行。
在 Apache 1.x 中,对于给定的钩子,只能触发一个处理程序。在 Apache 2.0 中,每个处理程序不仅为给定的钩子注册自己,还指示它希望相对于其他模块何时执行;例如,mod_speling 将其处理程序注册为最终处理程序 (APR_HOOK_LAST)。如果另一个模块注册了 fixup 处理程序,它将在 mod_speling 之前执行。对于给定的钩子,可以触发多个处理程序这一事实开启了以前难以实现的各种可能性。
类似地,Apache 现在允许一个模块过滤或修改另一个模块的输出。mod_backhand 目前可以做到这一点,但该模块依赖于 Apache API 中的许多技巧和阴暗角落。Apache 2.0 旨在允许模块充当输入或输出过滤器。这意味着,如果您想为 HTML 页面添加一组标准的页眉或页脚,您现在可以全面做到这一点,包括由 CGI 程序、服务器端包含和 mod_perl 处理程序动态生成的页面。
Apache 配置系统现在使用 GNU autoconf,而不是 1.x 版本中使用的 Apache 特定系统。并且,以前版本的 Apache 中包含的许多 C 语言抽象(例如哈希表和字符串)现在已被命名为 Apache 可移植运行时 (APR)。APR 包含在 Apache 中,并在您构建服务器时自动配置和编译到服务器中。
最后,Apache 现在附带 mod_ssl,它提供 SSL 和 TLS 加密。Apache 1.x 不仅未能附带这样的模块,而且这两个模块(Apache-SSL 和 mod_ssl)不兼容,并且在安装之前需要修补 Apache 源代码。mod_ssl 现在将成为每个 Apache 安装的标准组成部分,这对于网站管理员来说是一个巨大的解脱,并且非常受欢迎。
UNIX 系统长期以来都具有同时运行多个进程的能力。我通常在我的 Linux 机器上运行 Emacs、GNOME 终端和 Galeon;虽然粗略一看可能只显示这三个进程,但实际上还有数十个进程(sendmail、gnome-panel、Apache、syslogd 等)在没有我直接知情的情况下执行。要获得计算机上运行的完整列表,我可以使用命令 ps aux。
好消息是,进程模型简单易懂,确保了系统的稳定性,并且可以跨多个操作系统移植。不幸的是,然而,进程相对笨重且速度较慢。Linux 用户在这方面尤其被宠坏了,因为在 Linux 上创建新进程是一项非常轻量级的操作。但即使在 Linux 上,生成新进程有时也可能有点极端。
因此,多年来,线程的替代模型已经发展起来。使用线程,单个进程可以在多个位置同时执行。线程提供了进程的许多优点,而没有开销。但也有代价:使用线程进行编程可能非常棘手,因为始终有可能一段特定的代码在两个不同的线程中执行。您始终可以编写(或重写)代码以使其线程安全,但这通常是一项艰巨的任务。
由于线程既困难又棘手,并且由于 Apache 最初设计为仅在 UNIX 机器上工作,因此 Apache 1.x 专门在进程级别工作——如果您想处理十个并发 HTTP 请求,那么您必须运行十个 Apache 进程。由于创建新进程需要时间,因此 Apache 1.x 从 NCSA HTTPd 中借鉴了一个想法,即在实际需要进程之前预先派生进程。这意味着 Apache 的启动速度可能有点慢,但处理传入连接不会花费太多时间。Apache 还允许管理员指示应始终存在多少“备用服务器”,并根据需要添加和删除 Apache 进程。
预派生的 Apache 服务器稳定、易于理解且健壮。但是在许多系统上,使用进程不如使用线程。特别是,Windows 比进程更多地使用线程,这意味着通过坚持使用进程,Apache 在渗透 Windows 市场的能力方面受到了限制。
Apache 2.0 使用 MPM(多处理模块)解决了这些问题。每个 MPM 都是一个 Apache 模块,用于处理进程和线程的细节。在 Windows、OS/2 和 BeOS 上,这意味着您最终可以使用操作系统原生的线程机制运行 Apache。在 UNIX 和 Linux 系统上,您可以尝试多种不同的模型,选择适合您需求的模型。
当您安装 Apache 时,prefork MPM(其运行方式与 Apache 1.x 完全相同)是默认选择。Linux 用户的另外两个选择是:1) worker:线程数上升和下降(根据传入请求的数量),但进程数保持不变;2) perchild:每个进程包含固定数量的线程,但这种进程的数量会根据传入请求的数量而上升和下降。
现在说还为时过早,但我预计随着时间的推移,会出现更多的 MPM,并且会有许多模块利用线程来池化数据库连接、共享应用程序数据以及在后台生成异步任务。
从 httpd.apache.org/dist/httpd 获取最新的源代码;截至撰写本文时,最新版本为 2.0.35。在临时目录中解压缩源代码
cd /tmp tar zxvf httpd-2.0.35.tar.gz
您现在可以使用一个或多个参数运行 configure 程序。这些参数大致分为四类:1) Apache 应安装到哪个目录?2) 您想使用哪个 MPM?3) CGI 程序应在哪个用户 ID 下执行?4) 您想安装哪些模块?在这些模块中,哪些应该动态安装(使用共享库)而不是静态安装?
您可以通过键入 ./configure --help 获取配置选项的完整列表。如果您想包含默认情况下未包含的模块,则尤其如此。配置中最大的变化是模块现在有自己的选项来激活它们。对于使用“worker”MPM 的最简单配置,请键入
./configure --with-mpm=worker
之后,运行 make,然后运行 make install。(截至撰写本文时,Apache 没有 make test。)默认情况下,Apache 2.0 安装到 /usr/local/apache2。您可以使用与 Apache 1.x 相同的程序 apachectl 启动它,该程序通常位于 /usr/local/apache2/bin/ 中
/usr/local/apache2/bin/apachectl start服务器很快就会启动。HTML 文档通常保存在 /usr/local/apache2/htdocs 中,因此您应该已经能够将 HTML 文档放在那里并查看它们。
Apache 的运行时配置仍然依赖于一个文本文件,通常称为 httpd.conf。如果您熟悉 Apache 1.x,那么您会很高兴知道几乎所有现有指令都将继续工作。您必须学习的主要指令是那些与线程相关的指令,假设您使用 worker 或 perchild MPM。
当 Apache 软件基金会宣布 Apache 2.0 时,该公告明确表示新版本是最稳定且推荐用于生产的版本。在很大程度上,我相信他们;www.apache.org 每天接收的请求比我的服务器多得多,并且他们已经运行 Apache 2.0 beta 版本一年多了。因此,可以肯定地说,Apache 2.0 对于大多数站点来说足够稳定。
此时避免切换到 Apache 2.0 的主要原因是如果您需要 mod_perl 或 PHP;它们目前仍在测试中,但在您阅读本文时可能会可用。
正如我上面提到的,然而,很难正确处理线程,在 Perl 中尤其如此,Perl 在过去几年中尝试了多种线程模型。如果您使用 ithreads 编译了 Perl,那么您可以使用它为 Apache 2.0 创建一个 mod_perl,它使用 worker 或 perchild MPM。但是这种配置的稳定性如何还有待观察;很可能 mod_perl 用户现在会选择坚持使用 prefork MPM,直到尘埃落定。
Apache 2.0 提供了 Web 开发人员想要的一切——更多的模块、更多的灵活性和更快的速度。如果您还没有尝试过 Apache 2.0,我鼓励您下载它并使用您站点的配置对其进行测试,以验证它是否是一个不错的选择。
电子邮件:reuven@lerner.co.il
Reuven M. Lerner 是一位专门从事 Web/数据库应用程序和开源软件的顾问。他的著作《Core Perl》于 2002 年 1 月由 Prentice Hall 出版。