3个版本 (破坏性更新)
0.3.0 | 2021年6月21日 |
---|---|
0.2.0 | 2021年6月16日 |
0.1.0 | 2021年6月11日 |
#2 in #door
355KB
336 行
PortunusD
portunusd
是一个受 OpenBSD 的 relayd
和 heirloom UNIX inetd
启发的网络应用服务器。它监听传入的网络连接,通过 illumos door 将传入数据转发到目标应用程序,并以类似的方式返回响应。 portunusd
将每个连接的端口映射到由目标应用程序提供的文件系统上的 door。
portunusd
的主要目标是便于单线程应用程序的扩展。在 inetd
模型下,会为每个请求创建一个新的进程。通过利用 doors,portunusd
仅在达到新的并发峰值时才在应用程序进程中创建新的线程;否则,将重用现有线程来处理后续请求。
问题陈述
我们希望我们的面向网络的程序能够根据用户需求进行扩展。我们希望当程序空闲时,将程序的资源成本最小化,并希望我们的成本与需求呈线性关系。我们希望将应用程序开发人员对资源管理的责任最小化,并希望尽可能保留(UNIX 命令行工具的)熟悉开发环境。
以 Rails 为例,单线程的 Ruby on Rails 应用程序一次只能处理一个用户请求。在没有多个驻留在内存中的应用程序副本(在单独的 Ruby 解释器中)的情况下,无法处理多个同时请求。这种模型在用户需求很少时也会消耗大量的内存,这使得主机难以运行其他工作负载。随之而来的是大量的页面交换和磁盘磨损。
Node.js 等环境通过使异步性对程序员更加透明来处理这个问题。虽然拥抱计算机的异步性可能会有所帮助,但它也引入了对支持它的语言的变化;这不仅仅是一个语法的改变,也是对阅读、编写和理解程序的思维模式的一个非平凡的改变。
在光谱的另一端,CGI 应用需要为每个请求提供独特的进程和地址空间。这些应用可以根据用户需求线性扩展,包括在空闲时减少到零内存/ CPU 使用,但为每个请求调用 execv(2)
的成本可能会影响吞吐量。
后现代的“无服务器”方法满足这些标准,但代价是 放弃操作系统。这是一种完全陌生的软件开发方法,并且放弃了在运行时观察和调试应用程序的许多工具。
论文
门(Doors)使网络应用程序开发采用了一种新的(旧的?)模型,其中开发者负责维护和理解一个线性、同步的任务,而操作系统和 Web 服务器共同解决扩展问题。
- 当一个应用程序处于空闲状态时,只需要在内存中保留一个副本。
- 当请求进入系统时,可以由现有的线程处理。
- 只有在达到新的并发峰值时才会创建新的线程。
这些特性使我们能够通过开发类似单线程 UNIX 命令行工具的网络应用程序来解决我们的问题陈述,这些应用程序在空闲时具有最小的开销,并且按请求粒度线性扩展。
当然,门本身无法处理跨越单个操作系统实例边界的扩展,但与防火墙的 relayd 风格合作可以促进这一点,假设应用程序的副本可在多个主机上可用。这正是 portunusd
发挥作用的地方。
致谢
社交媒体预览图像由 Loudon dodd 提供 - 自有作品,CC BY-SA 3.0。
许多关于 illumos / Rust / Doors 的问题由 @jasonbking 回答。
依赖项
~1.5MB
~26K SLoC