加载失败
这篇文章讨论的是 reverse proxy 到后端应用服务器的通信协议:继续用 HTTP,还是用 FastCGI 这种为应用进程设计的专用二进制协议。FastCGI 起源于对 CGI 的持久化改造,后来常见于 PHP-FPM(PHP 的 FastCGI 进程管理器)、nginx(高性能反向代理/HTTP server)、lighttpd 和 Apache 的 mod_proxy_fcgi 之类的部署。评论把它放回 90 年代末到 2000 年代的 FastCGI/SCGI/HTTP 之争,也联系到云时代“所有东西都用 HTTP”以及 Google 内部 Stubby(内部 RPC/传输协议)这类更专用的内部链路。争点不只是性能,还包括 header 可信边界、TLS termination、认证、DDoS 过滤,以及开发时能否直接用浏览器连应用。
不少评论认为 FastCGI 这类专用协议比 HTTP 更适合反向代理到后端应用这一段,因为它把控制信息和请求/响应 body 分开,减少 framing、解析和边界歧义。有人还介绍了 Web Application Socket(WAS),用控制 socket 加两个 pipe 传输原始数据,连 splice() 这种零拷贝操作都能直接用,并且支持可取消请求和恢复文件描述符。支持者强调,FastCGI 的参数模型能把可信元数据与普通 HTTP 头分层,避免把一堆本不该交给应用的东西一并透传。也有人提到 uWSGI 在这类场景里同样是成熟的“小而全”二进制协议。
[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7] [来源8]
另一派把 HTTP 的胜利归因于简单和通用:反向代理本来就要处理 HTTP,把同一种协议一路转给后端,能让开发、测试和生产保持一致。评论里回顾了 FastCGI、SCGI、HTTP 当年的路线之争,认为 HTTP 让多级 reverse proxy、SSL termination、认证和 DDoS filtering 都更容易组合。nginx(高性能反向代理/HTTP server)的成熟也被反复提到,它比当时很多 FastCGI/SCGI 模块更快、更稳,足以压过协议层面的“更优雅”。还有人直接把这看作 web 世界版的 Worse is better。
[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7] [来源8] [来源9]
很多争论其实都落在“谁能信任哪些 header”上。评论举了 X-Forwarded-For、X-Real-IP、True-Client-IP、Forwarded 等常见来源信息头,指出它们不仅命名混乱,还可能被客户端伪造,导致后端误判真实来源。有人建议在 nginx 里关闭 `proxy_pass_request_headers`,然后只显式转发需要的字段;也有人提到 HAProxy 的 Proxy Protocol 和标准化的 Forwarded header,但它们都有兼容性或 multiplexing 限制。FastCGI 被看好的原因之一,就是只有 web server 能构造的参数天然更像可信边界。
[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7] [来源8]
评论里充满了部署史:PHP 从 mod_php 迁到 PHP-FPM(PHP 的 FastCGI Process Manager)后,FastCGI 才在大规模 PHP 生态里真正普及;Apache、lighttpd、nginx 也各自提供了不同的接入方式。有人回忆 uWSGI 在 Python、Ruby、Perl 圈里其实很好用,带有 draining、autoscaling、logging、chrooted backends 甚至 websockets/async,只是 cloud era 后热度下降。另一批人则觉得现在教程和云平台都默认“直接用 HTTP”,再加上嵌入式 HTTP server、WAF、Cloudflare Tunnel 这些方案,让额外协议栈显得不值得。还有人顺手提到老牌工具如 mongrel2、mod_proxy_fcgi、FCGI::ProcManager 之类,基本都属于同一条演化链。
[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7] [来源8] [来源9] [来源10] [来源11]
关于能力边界,也有不少补充。有人指出 FastCGI 对 WebSockets 不友好,但 SSE(Server-Sent Events)和 WHATWG streams 可以部分替代长连接/流式需求,做双向流通常要用一对请求。也有人提醒传统 CGI 的环境变量传 header 有 `httpoxy` 之类的老坑,而 `PATH_INFO`、URL 解码和 `%2F` 的处理会让语义变得更“丢信息”。有人甚至认为 HTTP/2/3 已经补足了 framing 和 multiplexing,但这并没有解决 header 可信边界的问题。
[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7] [来源8]
CGI: 传统网关接口,把 HTTP 请求映射为一次外部进程执行,早期动态网页的基础方案。
FastCGI: CGI 的持久化扩展,用二进制协议让 web server 与应用进程长期通信。
SCGI: 一种更轻量的 CGI 风格协议,曾在 Python 生态中较常见。
uWSGI: 一个二进制协议及其服务器/进程管理器,常用于 Python 等 Web 部署。
PHP-FPM: PHP FastCGI Process Manager,PHP 在生产环境里常见的 FastCGI 进程管理方式。
Proxy Protocol: 在 TCP 连接层携带客户端真实 IP、端口等元数据的协议。
Forwarded / X-Forwarded-*: 代理链中传递来源信息的 HTTP 头或事实标准头族,但容易混乱和被伪造。
End-to-End Principle: 端到端原则,强调中间层尽量不理解应用语义,把逻辑放在两端。
Principle of Least Privilege: 最小权限原则,只转发或暴露完成任务所需的信息。
Server-Sent Events(SSE): 基于 HTTP 的单向流式推送机制,适合持续向客户端发送事件。