Web 应用程序设计中是否已经放弃了 Unix 哲学?

Web 应用程序设计中是否已经放弃了 Unix 哲学?

Unix 哲学鼓励使用小型的、一般可重用的协作程序,这些程序与管道、fifo、套接字等进程间通信形式进行协作,而不是共享内存空间和链接。 MH 和 uzbl 程序经常被作为应用程序的示例,在其设计中体现了 Unix 哲学。

如果真是这样,那么 Unix 哲学在 Web 应用程序的设计中不是已经完全被抛弃了吗?几乎所有处理请求的 Web 应用程序现在都构建为单个大型、长期运行的进程,这些进程不仅处理一种资源,而且处理整个域中的所有资源的整个请求/响应周期(除了对外部数据库程序的调用)。

这主要是因为通过管道传输到外部程序集合来构建对 Web 请求的动态响应会导致进程启动时间开销过大吗?如果你想通过管道输出到 Ruby 或 Python 脚本,我可以理解这种情况,但也许如果你使用像 Haskell 这样可以编译的语言,那么在构建 Web 应用程序时遵循 Unix 哲学的任何真正障碍就会消失?

答案1

我认为这在很大程度上取决于您在应用程序之间划定界限的位置(即您对应用程序的定义是什么)以及您考虑的用例。

wget虽然您可以将 Web 浏览器实现为/的合并curl,但 HTML/XML 解析器将为每个文档节点调用简单的应用程序,独立的 JavaScript 引擎将与所有这些进行交互,以及“简单”的显示器将“只是”将上述内容的输出放在屏幕上(并将输入返回到某个核心协调进程),它会比(可能是任何)当今其他浏览器更混乱。

至于将数据通过管道传输到外部进程 - 实际上就是这样开始了。如果您担心平均 Web 应用程序代码的大小,是的,它们通常很大(通常是因为它们是位于用解释性编程语言编写的平台之上的一层,而不是“简单”应用程序),但是比较一下到他们的同等水平。电子邮件客户、办公套件......应有尽有。所有这些都非常复杂,并且具有太多功能,无法作为通过管道进行通信的几个进程来实现。您使用这些应用程序执行的任务通常也很复杂。复杂问题没有好的简单解决方案。

也许是时候看看 UNIX 座右铭“做的很少但擅长的应用程序”背后的动机了。将“应用程序”替换为“通用模块化单元”,您就可以得到基本的良好编程实践之一:模块化地做事,以便部件可以重复使用和单独开发。恕我直言,这才是真正重要的(编程语言的选择与之无关)。

附注 (在评论之后):从最严格的意义上来说,您大多是对的 - Web 应用程序没有遵循 UNIX 哲学(被分割成几个较小的独立程序)。然而,应用程序的整个概念似乎相当模糊——sed在某些方面可能被认为是应用程序。情况,而它通常只充当过滤器。

因此,这取决于你想从字面上理解它。如果您使用进程的通常定义 - 作为单个进程运行的东西(在内核看到它的意义上),那么例如由模块在 httpd 中解释的 PHP Web 应用程序则完全相反。加载的共享库是否仍属于单个进程的范围(因为它们使用相同的地址空间),或者它们是否已经更加独立(从程序员的角度来看是不可变的,完全可重用并通过定义良好的 API 进行通信)?

另一方面,当今大多数 Web 应用程序都分为客户端和服务器部分,它们作为单独的进程运行 - 通常在不同的系统上(甚至物理上独立的硬件)。这两个部分通过明确定义的(通常是文本的)接口(基于 HTTP 的 XML/HTML/JSON)相互通信。通常(至少在浏览器中)有几个线程正在处理应用程序的客户端(JavaScript/DOM、输入/输出...),有时甚至是运行插件的单独进程(Java、Flash...)。这听起来和最初的 UNIX 哲学一模一样,尤其是在 Linux 上,其中线程流程通过(几乎)任何帐户。

除此之外,服务器部分几乎总是分为几个不同的部分 - 对结构化(或非结构化)数据执行请求的操作的单独数据库引擎就是一个典型的例子。将数据库集成到 Web 服务器中并没有多大意义。然而,将数据库拆分为多个进程也没有多大意义,这些进程专门用于解析请求、从数据存储中获取数据、过滤数据……人们必须在创建一个无所不能的庞然大物和一个一群几乎为零的工人,大部分时间都在互相交谈。

至于文本的接口:请注意,40 年前处理的数据的情况在今天不一定是正确的 - 二进制格式在反/序列化所需的空间和功耗方面都更便宜,并且数据量要大得多。

另一个重要的问题是,UNIX 哲学的目标实际上是什么?我不认为数值模拟、银行系统或可公开访问的照片库/社交网络曾经如此。系统维护然而,运行这些服务肯定已经并且很可能将来也会如此。

答案2

我不确定 Unix 哲学是否曾经出现在 Web 应用程序设计中 - 然而,虽然许多 Web 应用程序的行为可能确实如您所描述的那样,但人们可能会认为现在的 Web 应用程序更有可能是数据消费者(考虑到越来越多的 API/Web 服务驱动的为 Web 消费生成数据的方法)。
这反过来可能会被视为鼓励使用相互协作的小型、可重用组件(以 JavaScript 函数的形式),因此可能存在小型并行。

相关内容