Apache —— Web 服务器的"老贵族",三分天下有其一
一、先说两句
在 Nginx 流行之前,整个互联网的 Web 服务器只有一个名字:**Apache**。
它 1995 年出生,比 Google 还早。到 2000 年代初期,全球超过 60% 的网站跑在 Apache 上。虽然现在被 Nginx 超过了,但仍然有大约 **三分之一的网站** 在使用它。
Apache 的全称是 **Apache HTTP Server**(也叫 httpd)。它的诞生故事很有意思——最初是一个叫 NCSA 的 Web 服务器项目停了,一群开发者自己打补丁维护,最后拼凑出一个新项目,取名 "A Patchy Server"(一堆补丁的服务器),后来演变成了 Apache。
它的核心设计哲学和 Nginx 完全相反:
```
Nginx 的理念:
功能少而精,能做的就几件事,但每件都做到极致
配置集中管理,严格而清晰
Apache 的理念:
功能多而全,什么都能做,靠模块堆能力
配置极度灵活,每个目录都能单独改
```
这两种理念没有对错,只是取舍不同。**Nginx 选择了性能和简洁,Apache 选择了兼容和灵活。**
这也是为什么在 2025 年的今天,Apache 仍然有它的生存空间——有些场景下,灵活比性能更重要。
二、Apache 为什么能活三十年?
**1. 模块化架构 —— 想要什么功能就加载什么功能**
Apache 的核心很轻量,几乎一切功能都是通过模块(Module)实现的:
```bash
Apache 的模块系统:
核心功能 → 啥也没有,就一个 HTTP 服务器骨架
加模块 → 加功能
常见模块:
mod_php → 直接处理 PHP(不用 PHP-FPM)
mod_ssl → HTTPS 支持
mod_rewrite → URL 重写(伪静态)
mod_proxy → 反向代理
mod_alias → 路径别名
mod_auth → 用户认证
mod_deflate → Gzip 压缩
mod_cache → 缓存
mod_status → 服务器状态监控
mod_security → Web 应用防火墙(WAF)
… 还有上百个
```
**想用哪个加载哪个,不想用就不加载。** 这让 Apache 可以极其轻量(只装需要的模块),也可以极其强大(全模块加载)。
**2. .htaccess —— 每个目录都能独立配**
这是 Apache 最独特、也最受争议的功能。
```bash
# Nginx:改配置要编辑 /etc/nginx/nginx.conf
# 改完要 nginx -s reload
# 普通用户没权限碰配置
# Apache:每个目录放一个 .htaccess 文件
# 改完即时生效,不需要重启
# 不需要 root 权限
# .htaccess 能做到的事情:
RewriteEngine On
RewriteRule ^article/([0-9]+)$ /show.php?id=$1 [L]
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /path/to/.htpasswd
Require valid-user
Redirect 301 /old-page.html /new-page.html
```
对**虚拟主机用户**来说,.htaccess 就是神——你不需要联系服务器管理员,自己上传一个文件就能改网站的行为。
对**系统管理员**来说,.htaccess 是噩梦——每次请求都要检查每个目录有没有 .htaccess 文件,性能开销不小。
**3. 兼容性 —— 什么老项目都能跑**
Apache 对老技术的支持是最好的:
```bash
Apache 还在支持的东西(Nginx 不爱管的):
- CGI 脚本(1993 年的技术)
- SSI(Server Side Includes,1995 年的模板技术)
- mod_perl(直接在 Apache 里跑 Perl)
- .htpasswd 基本认证(最古老但最简单的登录方式)
- FTP 集成(某些发行版)
- IPv4/IPv6 双栈(很早就支持了)
- 各种认证后端(LDAP、DBM、SMB……)
```
如果你的公司还有**跑了十几年的老系统**,大概率跑在 Apache 上。不是因为它有多好,而是因为它兼容一切。
**4. 动态内容处理 —— mod_php 的便利**
LNMP 架构里,PHP 是通过 PHP-FPM 单独跑的,Nginx 用 FastCGI 连上去。
Apache 的处理方式简单得多:
```apache
# 加载 PHP 模块
LoadModule php_module modules/libphp.so
# 告诉 Apache .php 文件交给 PHP 处理
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
```
**没有独立的 PHP 进程、没有 FastCGI 的配置、没有 socket 连接。** PHP 直接在 Apache 进程里运行,配置简单到极致。
当然,这也意味着每个 Apache 进程都要带着 PHP 解释器,内存占用更大。**简单和性能,总得选一个。**
三、Apache 的两种工作模式
Apache 有两种处理请求的方式,直接影响性能和内存占用:
**1. Prefork(预派生)模式**
```bash
# 配置
<IfModule mpm_prefork_module>
StartServers 5 # 启动时创建 5 个进程
MinSpareServers 5 # 最少空闲 5 个
MaxSpareServers 10 # 最多空闲 10 个
MaxRequestWorkers 150 # 最多 150 个进程同时工作
MaxConnectionsPerChild 10000 # 每个进程处理 10000 个请求后重启
</IfModule>
```
特点:
```
✅ 每个请求一个独立进程,互不干扰(一个挂了不影响别的)
✅ 兼容所有模块(包括 mod_php)
❌ 内存占用大(150 个进程 × 每个几十 MB = 好几个 GB)
❌ 并发能力有限
```
**适合:** 跑 PHP 的网站、需要 mod_php 的场景、稳定性优先的应用。
**2. Worker(混合线程)模式**
```apache
# 配置
<IfModule mpm_worker_module>
StartServers 3
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 10000
</IfModule>
```
特点:
```
✅ 每个进程里开多个线程,每个线程处理一个请求
✅ 内存比 Prefork 小得多
✅ 并发能力比 Prefork 强
❌ 不能加载 mod_php(PHP 很多函数不是线程安全的)
❌ 一个线程挂了可能影响同一进程的其他线程
```
**适合:** 纯静态内容、代理场景、不用 mod_php 的应用。
**3. Event 模式(Apache 2.4+,推荐)**
```apache
<IfModule mpm_event_module>
StartServers 3
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 10000
</IfModule>
```
特点:
```
✅ 在 Worker 基础上改进了长连接的处理(空闲连接不占用线程)
✅ Apache 2.4 以后性能最好的模式
✅ 接近 Nginx 的事件驱动效果
❌ 仍然不能加载 mod_php(和 Worker 一样的问题)
```
**这个模式让 Apache 在高并发下的表现改善了很多**,虽然还是比不上 Nginx,但差距缩小了很多。
四、最常用的配置
**1. 虚拟主机 —— 一个 Apache 跑多个网站**
```apache
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
<Directory /var/www/example.com>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/example.com_error.log
CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined
</VirtualHost>
<VirtualHost *:80>
ServerName another.com
DocumentRoot /var/www/another
<Directory /var/www/another>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
```
**2. URL 重写(伪静态)—— 靠 mod_rewrite**
这是 Apache 最常用的功能之一:
```apache
RewriteEngine On
RewriteRule ^article/([0-9]+)$ /show.php?id=$1 [L,QSA]
RewriteRule ^category/([a-z]+)$ /list.php?cat=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php [L]
```
WordPress 的 .htaccess 就是最经典的例子:
```apache
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
```
这四行就是 WordPress 伪静态的核心——如果请求的不是真实文件或目录,全部转发给 index.php。
**3. HTTPS**
```apache
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
<Directory /var/www/example.com>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
# HTTP → HTTPS 跳转
<VirtualHost *:80>
ServerName example.com
Redirect permanent / https://example.com/
</VirtualHost>
```
**4. 反向代理**
```apache
<VirtualHost *:80>
ServerName app.example.com
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
<Location />
Require all granted
</Location>
</VirtualHost>
```
五、Apache vs Nginx —— 现在还选 Apache 吗?
| 维度 | Apache | Nginx |
|------|--------|-------|
| 架构 | 进程/线程 | 事件驱动(异步) |
| 静态文件性能 |
Apache —— Web 服务器的"老贵族"
文章评论 0 条
U
👍
👎
@
K
Kevin
2 小时前
Rust 的 async 生态终于要完善了!Async Iterator 和 async closure 这两块一直是我觉得最欠缺的。期待今年的进展!
👀 12
💬 回复
S
Sarah
5 小时前
编译速度优化这块太重要了,我们项目从 5 分钟降到 2 分钟就是巨大的效率提升。期待并行前端解析的上线。
👀 8
💬 回复
查看更多评论 →