跳到主要内容
专题 · Web 作为系统能力

网站如何变成必须运营的应用系统

Robert
ARCArchitectureWebsite

当一个网站开始有大量内容、用户和业务状态时,数据库往往成为自然选择。把文章、账户、权限和交易都直接散落在服务器目录里,并不能带来真正的可维护性。CMS 让编辑与发布有了共同入口;应用服务器让规则和数据访问有了清楚的执行位置;数据库让内容可以被查询、排序、更新和控制访问。

这套架构改变了 Web。一个站点不再只是“服务器返回哪份文件”,而是“Web 服务器把请求交给应用,应用从数据层取回状态,再生成合适的响应”。Java Servlet、JSP 与 J2EE 式服务端应用让应用服务器、数据库和事务性逻辑成为重要路线;2004–2005 年出现的 Rails 与 Django 又把路由、ORM、迁移、模板和脚手架收进更有约定的体验。它们没有发明 MVC、数据库或全部现代 Web 实践,却把这套模型带给了更多团队。对需要长期运营的产品来说,这是一种重要的成熟,而不是简单的技术膨胀。

这也改变了人们实际使用网站的方式。以 2000 年代常见的内容站为例,编辑不再通过 FTP 替换一个 HTML 文件,而是在浏览器的后台登录、填写标题和正文、点击发布;文章、作者和分类进入数据库。读者访问同一篇文章时,服务器在请求到来后取回记录、套进模板,再把页面送回浏览器。作者看见的是 CMS,读者看见的是网页,运维人员看见的则是一台应用服务和一套需要备份、升级、监控的数据系统。应用运行时出问题时,即使磁盘上还留着图片,也不一定能重新生成那篇文章。三者面对的已经不是同一个“文件夹”。

但它也改变了发布的默认成本。以前只想更新一篇内容,可能只是替换一个文件;后来它常常意味着进入 CMS、连接数据库、跑构建、部署服务、维护权限、处理备份和升级。内容本身没有变得更难写,周围的系统却变成每个发布者都必须面对的基础设施。

浏览器成为 runtime,复杂度又向两边生长

Ajax 的流行让浏览器不再只是在每次请求后重画一页。应用可以在客户端保留状态、异步加载数据、局部更新界面。单页应用进一步把路由和呈现的大量工作移到浏览器里。React 等组件模型让大型前端可以组织得更好,也让“网页”越来越像一个在浏览器中持续运行的应用。

再往后,读者会先拿到一个应用外壳,浏览器下载 JavaScript,再向 API 请求数据并在本地更新页面。开发团队也随之把工作拆成前端构建、后端服务、接口契约、部署环境和缓存策略。对于在线协作、控制台或复杂表单,这种体验比整页刷新自然得多;但一篇只希望被读到的文章,也开始被放进同一套工程方法里考虑。

这同样解决了真实问题。一个仪表盘、协作文档或复杂表单,本来就需要连续的交互反馈。可对内容站点而言,新的问题也出现了:初始页面如何被快速读到?深链接怎样工作?搜索引擎和社交抓取器看见的是什么?因此服务器渲染、静态生成和混合渲染又重新成为重要选择。

这里没有一个唯一正确的方向。浏览器 runtime、服务器渲染和预生成页面,是为不同交互和发布需求服务的工具。真正不必要的是把它们看成每个页面都必须从头选型、从头部署的一整套应用架构。

对象存储和 Git 驱动的静态发布让这个问题得到过一次很漂亮的缓解。Amazon S3 的静态网站功能与 GitHub Pages 先后表明,存储层和版本控制可以直接承担部分公开 Web 的职责;Netlify 在 2015–2016 年把 Git 构建与 Deploy Previews 产品化。ZEIT 的 now 从简化部署起步,后来更名为 Vercel,延续了 Git → preview → shipping 的工作流,也承载静态交付之外常见的服务器渲染、函数/API 路由和 edge runtime 工作。它们不是“第一个”、不是同一种实现,也不替团队解决所有后端或全栈需求;共同证明的是,许多站点真正需要可靠的发布路径,而不是一台始终运行的应用服务器。

ArcBlock 走的是不同的路。2020 年发布的是 ABT Node 1.0,2021 年末才更名为 Blocklet Server:它是一种可自行部署和管理的 runtime,用来安装、组合、运行和管理静态或动态 Blocklet,并把路由、DID/身份、授权与生命周期带到同一运行环境。它与 Netlify 或 Vercel 的共同点是减少部署和运行摩擦,不是互为替代品。2023 年起,v0 把提示生成 React/Tailwind/shadcn UI 的入口提前;2024–2025 年的 Lovable 则把提示构建、预览与显式发布组织在一起。自然语言让开始构建更容易,但部署、数据、身份、权限与运行时仍是需要被明确承担的边界。

把发布重新从应用运行中拆出来

ARC 的 Web Device 就在这里取一个很窄的位置。它不试图决定所有网站该用静态生成、服务器渲染还是浏览器 runtime;它也不要求动态数据从此消失。它只是把发布型页面常见的共同工作收进系统层:站点声明、页面与内容资源的发现,HTML 的组装,预览,链接和基本 SEO 检查,以及发布工作流。

重要的是,系统并不要求这些发布事实先复制进一套独立的 CMS,再由另一个服务把它们取出来。AFS 可以把实际的数据源、内容、配置和可调用能力组织在同一套路径模型里。Web Device 只负责从中构成面向读者的文档输出。数据需要更新、索引需要重建或特殊逻辑需要执行时,相关 provider 可以承担自己的责任;发布层不必假装自己拥有全部业务。

这也让“静态”有了更准确的意思。对发布型页面,稳定的预生成输出是优点:访问快、可索引、易于检查和部署。但只要页面依赖持续会话、即时协作或运行时状态,它就不应被伪装成静态站。ARC 会在这样的场景把工作交给 UI Device 或适当的运行时目标,而不是把所有需求塞进 Web Device。

下一篇会转向另一个被应用栈掩盖的问题。即使一份内容可以被漂亮地发布,读者怎样回应它,作者又怎样在不交出自己的空间和数据的前提下处理这种回应?

延伸阅读