零中间层
Rust 与 PHP 之间没有任何中间层:不用 FastCGI,不走 socket,没有 Goridge,也没有 CGO,更不需要任何序列化。
说来矛盾,PHP 一直没有一个生产可用的自带 HTTP 服务器:内置的那个只是开发工具,php-fpm 又离不开 nginx 这样的外部 Web 服务器。
Rapira 把这个服务器补上了:它自带一个 HTTP 接入层,用 Rust 基于 hyper 写成。hyper 是 Rust 的底层 HTTP 实现,它从连接上读出每个请求,再把 Rapira 产出的响应写回去。
HTTP 请求与响应Rapira 用 Rust 编写,PHP 用 C 编写。Rust 直接调用 C 函数。因此,Rust 可以直接调用 PHP 函数。 Rapira 把解释器内嵌在服务器进程中。直接绑定控制解释器的初始化和请求处理。
这里没有 FastCGI,没有 Goridge,也没有 CGO:请求从不序列化,也从不离开进程。在 Classic 模式和 Worker 模式下,Rapira 直接写入超全局变量。
进程模型PHP 运行在独立进程中,Web 服务器通过 socket 上的二进制协议与之通信:每个请求被打包成 FastCGI 记录,发送过去,在另一端解包,响应再原路返回。
PHP worker 是独立进程,通过管道或 socket 从服务器接收请求。Goridge 就是这套交换的协议:每个请求和响应都要在一端序列化、在另一端解析。
PHP 解释器内嵌在服务器进程里,但宿主是用 Go 写的,而 Go 无法直接调用 C 代码。每次调用都要经过 CGO,这个中间层在每次跨越语言边界时都会带来开销。
ABI 是编译型语言之间的二进制契约。Rust 原生支持 C ABI:从 Rust 调用 C 函数,编译出的机器码与 C 自己的调用完全相同。