一位独立开发者在 2026 年做了一件近乎叛逆的事:他用 1994 年诞生的 CGI 技术和纯 C 语言,写出了一个带用户系统、Stripe 支付、Postmark 邮件推送和 SQLite 存储的商业 SaaS 平台 marketyour.games,而且整个前端零 JavaScript。

在这个微服务、K8s 容器和前端 node_modules 动辄数百兆的时代,这个项目的全量编译只需要数秒,日常修改后的增量编译不足 0.5 秒。上线部署不是敲一串复杂的 CI/CD 流水线,而是编译出一个静态链接二进制文件,直接覆盖线上目录。

marketyour.games 极简技术栈指标 < 0.5s 增量重编译耗时 3 个 外部底层库依赖 1 个 静态二进制可执行文件

这看起来像是一场对抗现代软件工业臃肿病的大捷,但拨开极简主义的情怀迷雾,事情远没有想象中那么美好。

BCHS 架构:砍掉所有中间商的极简实验

该项目的底层基于 BSD 社区推崇的 BCHS 架构,即 OpenBSD、C、httpd 与 SQLite。它彻底抛弃了现代 Web 应用的标准范式:前面放 Nginx,中间走反向代理,后端挂一个用 Go、Python 或 Rust 编写的常驻应用服务。

项目抛弃复杂现代框架,仅依赖四个单文件与轻量 C 库(示意图)
项目抛弃复杂现代框架,仅依赖四个单文件与轻量 C 库(示意图)

在这里,架构退回到了三十年前:

  • 没有前端工程化,HTML 和 CSS 直接由 C 语言业务逻辑输出,静态资源全部编译进单个二进制文件从内存提供。
  • 依赖链收缩到了极致,只引入了处理网络的 libcurl、处理加密的 libsodium,以及两个单文件代码 libcjson 和 SQLite amalgamation。
  • 部署等于覆盖单文件,新请求进来直接执行新程序,无需重启服务进程。
传统现代架构 vs BCHS 单二进制架构 现代主流方案(多层代理) Nginx 代理 → Node/Python 应用服务 数百依赖包 + 容器编排 + 独立数据库进程 marketyour.games(BCHS) httpd 网关 → slowcgi 直接派生进程 单个静态文件 + 嵌入 SQLite + 内存资源

开发者对这套体系的满意显而易见:依赖极少,供应链投毒的风险微乎其微;没有庞大的抽象层,代码逻辑完全在大脑掌控之内。

  • 结论.对于业务逻辑极其收敛的个人产品,极致的依赖压缩确实能换来极低的维护心智负担。

隐秘的代价:进程派生与数据锁的真实瓶颈

然而,CGI 规范自 2004 年发布 1.1 版本后便基本停滞,现代工业界放弃它从来不是因为盲目追逐新潮,而是因为它的运行机制存在物理极限。

每个请求重复派生进程,高频系统调用带来物理级开销(示意图)
每个请求重复派生进程,高频系统调用带来物理级开销(示意图)

在 OpenBSD 的默认配置中,处理请求的 slowcgi 虽通过 FastCGI 与 httpd 协议通信,但底层依然为每个请求调用 fork() 与 execve() 启动全新可执行程序,并不保留常驻进程。尽管现代操作系统的进程复制机制已经过深度优化,但在并发流量面前,高频的系统调用依旧是一笔不可忽视的 CPU 开销。更为关键的是,该文通篇并未给出任何有关吞吐量、延迟或并发表现的基准测试数据。

更严峻的问题藏在存储层。SQLite 官方文档明确警告:严禁跨 fork 继承数据库连接。在无常驻进程的 CGI 模式下,每一个进入的 HTTP 请求都必须经历一次打开数据库文件、初始化连接与重新编译 SQL 语句的过程。即使开启了 WAL 模式,高频的连接开启与关闭也会引发额外的检查点周期,一旦遭遇并发写请求,脆弱的无连接池设计立刻就会面临锁竞争泥潭。


刀尖跳舞:操作系统沙箱掩盖了内存原罪

如果说性能瓶颈在微型业务场景下尚可容忍,那么安全性层面的取舍则更加凶险。

操作系统沙箱剥夺权限,掩盖了手工解析的内存隐患(示意图)
操作系统沙箱剥夺权限,掩盖了手工解析的内存隐患(示意图)
安全不能寄托于开发者的万无一失,哪怕是在最底层的代码里。

这套架构之所以敢在没有现代 Web 框架防护的前提下裸奔,全因寄生在 OpenBSD 独特的系统特性之上:httpd 默认工作在 chroot 环境下,操作系统层面的 pledge 与 unveil 机制强行剥夺了进程非必要的系统调用权限和文件系统访问权。

CGI 请求生命周期与安全边界 1. 请求进入 httpd 监听端口 2. slowcgi 派生 fork + exec 启动 3. 业务与存储 手写转义 + SQLite 4. 隔离庇护 pledge / unveil 沙箱

但 OS 级的沙箱并不是万灵药。由于作者手写了整个协议解析层(包括 Cookie、Query 参数以及表单转义),C 语言底层的内存安全隐患(如缓冲区溢出、格式化字符串漏洞)被直接暴露在最前端的 HTTP 入口。倘若脱离了 OpenBSD 特有的沙箱环境,将这套逻辑移植到普通 Linux 发行版上,其面临的渗透攻击面将呈指数级放大。

  • 风险.用手工编写的底层逻辑替代经过工业界千锤百炼的 Web 框架,一旦出现解析失误,代价往往是灾难性的。

一场极客的浪漫反叛,而非通用解药

将 marketyour.games 当作反抗现代前端膨胀与云原生过度工程化的宣言,确实大快人心;但将其视作未来的方向,则是误读了现实。

半秒内重编译的极客手作,难以跨越现代化协作鸿沟(示意图)
半秒内重编译的极客手作,难以跨越现代化协作鸿沟(示意图)

这一方案之所以能够成立,核心前提在于它服务的是一个业务高度固化、流量极其有限的微型产品。当并发请求激增,缺乏常驻 Worker 进程池的架构会迅速显露疲态;当团队需要协作扩充业务,手写 HTML 拼接与手动内存管理带来的协作成本将迅速吞噬编译期省下的那几秒钟。

它证明了在特定受限规模下,古老的工具依然拥有优雅运转的生命力。但要让整个工程界倒退三十年去写 CGI,现实的物理规律与安全成本,绝不会答应。