我的理解是创建CGI脚本已成为过去,并且由于每次调用它时它的方式都被认为效率低下。但是,当你调用嵌入了php脚本的网页时,我看不出有什么不同,它仍然以某种方式分叉到另一个进程,那么为什么CGI被认为效率低下呢?
答案 0 :(得分:5)
每个请求都有两种“主流”方式:
您可以将解释器直接加载到服务器的进程空间中,并在启动期间预先执行多个set实例。 mod_php和mod_python大致采用了这种策略。
您可以为解释器创建持久进程,然后为每个请求预先生成或生成线程,通过套接字与服务器通信。 FastCGI就是这样使用的。
事件驱动的服务器虽然不是主流,但由于充分的理由而变得越来越普遍。他们依赖于大多数网站花费大部分时间阻止I / O的知识,只是转动他们的隐喻。每当请求需要执行任何I / O时,服务器都可以自由地开始处理另一个请求而无需使用select()和friends启动另一个线程/进程。这实际上是解决C10k problem的唯一方法。
答案 1 :(得分:2)
CGI分发每个请求。这意味着每次都要进行分叉/初始化的“重量”。
FCGI或mod_php只在服务器启动时或在负载增加时分叉。这意味着每个进程只进行一次设置(但它们不共享内存)。
Facebook的HipHop没有分叉(它将PHP转换为线程安全的C ++代码)。这允许所有PHP“进程”都存在于单个多线程C ++二进制文件中,从而大大加快和减少内存使用。
答案 2 :(得分:1)
有FastCGI,当你启动php二进制文件的某些实例时,它们会一个接一个地处理查询,这样就不会为每个请求反复启动这些进程。
此外,PHP通常作为apache模块运行,其生命周期与Web服务器相关联,因此当Apache将文件标识为调用 mod_php 的PHP脚本时,处理请求之间不会产生额外开销与网络服务器本身合作。
答案 3 :(得分:1)
CGI的开销主要来自于处理请求的Web服务器进程fork()
,启动shell,然后运行外部程序。
由于请求是一个外部程序,几乎每个与请求有关的事情都必须被复制到新shell的环境变量中 - 查询字符串,远程地址,身份验证数据等.POST数据通过它传递给脚本标准输入。所有这些都需要时间来复制和配置,增加了开销。
这是查询字符串必须长度受限的一个原因。某些操作系统对环境变量的名称有(并且仍然存在)长度限制,并且肯定限制了单个变量的内容可能有多大。 HTTP规范本身没有限制,但由于CGI机制和底层操作系统限制,有限长度的查询字符串成为常态。
答案 4 :(得分:0)
Microsoft IIS允许通过将库加载到其地址空间来在进程中解释脚本。 (较新版本的IIS更像FastCGI,因为实际的脚本执行是在单独的Web工作进程中执行的,尽管这取决于虚拟目录的配置设置。)