Web 应用架构基础
核心分层:Web 服务 vs Web 应用
任何一个 Web 程序都可以拆分为两个逻辑层:
用户 (浏览器)
↕ HTTP 协议
Web 服务 (Nginx/Apache)
↕ CGI/FastCGI/WSGI/uWSGI 等协议
Web 应用 (业务逻辑代码)
Web 服务(Web Server)
- 核心职责:处理网络请求,解析 HTTP 协议
- 匹配访问路径、管理连接、TLS 终止、静态文件服务
- 代表:Nginx、Apache、Caddy
Web 应用(Web Application)
- 核心职责:执行业务逻辑、生成动态内容
- 处理用户认证、数据库查询、付款逻辑等
- 代表:Django/Flask(Python)、Laravel/ThinkPHP(PHP)、Spring Boot(Java)
分层的好处:分工协作,各司其职。Web 服务开发者专注 HTTP,Web 应用开发者专注业务。
从静态到动态的演进
纯静态时代
最早的 Web 程序只提供静态内容——就像把报纸搬到网上,所有用户看到的内容完全一样。
Web 服务 ──→ 读取本地 .html / .css / .png 文件 ──→ 返回给浏览器
动态请求的诞生
用户不再满足于只读内容,需要交互(付款、搜索、留言等)。解决方案:
- Web 服务增加「调用外部程序」的能力
- 用 Perl、Python、Shell 等语言编写业务脚本
- 每个动态请求对应一个脚本
Web 服务 ──→ 识别动态请求 ──→ 调用外部脚本 ──→ 脚本执行业务逻辑 ──→ 返回结果
CGI — Common Gateway Interface
为什么需要 CGI?
在动态网站诞生之初,Web 服务与 Web 应用之间直接用 HTTP 协议通信,这意味着 Web 应用开发者也必须处理复杂的 HTTP 协议。CGI 的作用就是对 HTTP 协议进行封装,提供一个更简单的上层接口。
类比:HTTP 协议是一堆汽车零件,CGI 协议就是组装好的汽车——你不需要知道发动机怎么工作,只需要学会开车。
CGI 的工作原理
Web 服务(解析 HTTP)
↓ 按 CGI 协议组织数据
CGI 程序(Web 应用)
↓ 执行业务逻辑
返回结果给 Web 服务 → 返回给用户
CGI 的缺陷
每个动态请求都会:
- 创建一个新进程
- 处理完请求后销毁进程
- 下一个请求再来,重复创建
这在低并发时尚可接受,高并发下性能极差。
FastCGI — 长驻型 CGI
改进
FastCGI 本质与 CGI 相同(都是一种协议规范),但它是长驻型(long-live) 的:
- 进程处理完一个请求后不会关闭
- 继续等待处理下一个请求
- 避免了反复创建/销毁进程的开销
注意:CGI 和 FastCGI 都只是协议——一种规范/约定,就像快递单的填写规则。具体实现需要对应的程序(如 PHP-FPM)。
协议 vs 实现
| 概念 | 类型 | 示例 |
|---|---|---|
| CGI | 协议 | 规范定义 |
| FastCGI | 协议 | CGI 的升级规范 |
| PHP-FPM | 实现 | FastCGI 协议的一种具体实现 |
Web 框架的角色
Web 框架在 Web 应用内部进一步封装:
Web 应用
├── 上半部分(框架):解析 CGI/FastCGI/WSGI 等协议
│ + 提供常用功能(ORM、路由、模板)
└── 下半部分(开发者):专注编写业务逻辑
框架让开发者连 CGI/WSGI 协议都不用直接接触,专心写业务代码。常见 Web 框架:
- Python:Django、Flask、FastAPI
- PHP:Laravel、ThinkPHP、Symfony
- Java:Spring Boot、Spring MVC
参见
- PHP 体系架构 — PHP-FPM / FastCGI
- Python 体系架构 — WSGI / ASGI / uWSGI / Daphne
- 架构对比总结 — PHP vs Python
- Nginx — Web 服务器 / 反向代理
- 来源摘要