我为什么要避免使用CGI?

时间:2013-04-18 02:51:05

标签: ruby cgi fastcgi

我尝试使用CGI和ERB创建我的网站,但是当我在网上搜索时,我看到有人说我应该总是避免使用CGI,并始终使用Rack

我理解CGI会分叉很多Ruby进程,但是如果我使用FastCGI,只会创建一个持久进程,PHP网站也会采用它。加FastCGI接口只为一个请求创建一个对象,并且具有非常好的性能,而不是同时创建7个对象的Rack。

我不应该使用CGI的具体原因吗?或者它只是错误的假设,使用CGI / FastCGI完全没问题?

3 个答案:

答案 0 :(得分:1)

不要使用CGI。请。这不值得。早在20世纪90年代,当没有人知道更好的时候,这似乎是一个好主意,但那是脚本不经常使用,用于处理表单提交等特殊情况,而不是驱动整个网站。

FastCGI是一种“更好的CGI”的尝试,但它仍然存在很多方面的缺陷,特别是因为你必须管理你的FastCGI工作进程。

Rack是一个更好的系统,它运行良好。如果您使用Rack,您可以选择各种托管系统,甚至是Passenger,这非常简单可靠。

当你说Rack一次创建“7个对象”时,我不知道是什么意思,除非你的意思是有7个不同的Rack进程以某种方式运行,或者你在实现中犯了错误。

我想不出单个实例,其中CGI会优于Rack等效。

答案 1 :(得分:1)

CGI,我指的是接口和常见的编程库及其实践,是在不同的时间编写的。它将请求处理程序视为通过环境变量和标准I / O流连接到Web服务器的不同进程。

这是当时最先进的,当时我们没有真正的“网络框架”和“嵌入式服务器模块”。因此...

CGI往往很慢

同样,CGI模型每个连接产生一个新进程。虽然产卵过程本身目前很便宜,但是重型网络应用程序初始化 - 读取和解析模块的分数,建立数据库连接等等 - 使得这非常昂贵。

CGI倾向于过低级别(恕我直言)设计

同样,CGI模型明确地提到环境变量和标准输入作为请求和处理程序之间的接口。但谁在乎?这比应用程序设计师通常应该考虑的要低得多。如果你看看基于CGI的库和代码,你会发现它的大部分内容都鼓励“业务逻辑”以及表单解析和HTML生成,现在人们普遍认为它是一种危险的混合问题。

与Rack :: Builder等对比,编码器正在考虑将命名空间映射到一个动作,以及这对更广泛的Web应用程序意味着什么。 (突然之间,我们可以自由地争论语义网和REST的优点以及这个和那个,因为我们没有考虑根据用户提供的输入生成单选按钮。)

是的,类似Rack :: Builder的东西可以在CGI之上实现,但是,这就是重点。它必须是在CGI 之上构建的抽象层。

CGI倾向于被嘲笑

尽管CGI在其局限内完美地运作,尽管它很简单且被广泛理解,但CGI经常被解雇。如果您知道CGI,那么您也可能会被解雇。

答案 2 :(得分:0)

关于CGI,Rack等真正存在的问题存在很多困惑。正如我所描述的here,Rack是一个API,FastCGI是一个协议。 CGI也是一个协议,但从狭义上讲也是一个实现,而你所说的与FastCGI完全不同。那么让我们从背景开始吧。

回到90年代初,Web服务器只是从磁盘上读取文件(HTML,图像等)并将它们发送到客户端。人们开始希望在请求时进行一些处理,而早期的解决方案是运行一个程序,将结果发送回客户端,而不是仅仅读取文件。这个“协议”是为Web服务器提供一个URL,它被配置为作为程序执行(例如,/cgi-bin/my-script),然后Web服务器将设置一组具有各种环境变量的环境变量有关请求的信息,并在标准输入上使用请求正文运行程序。这被称为“Common Gateway Interface。”

鉴于这为每个请求分配了一个新进程,它显然效率低下,而且您几乎肯定不希望在高容量网站上使用这种动态请求处理方式。 (开始一个全新的过程在计算资源上相对昂贵。)

提高效率的一个解决方案是,不是启动新流程,而是将请求信息发送到已经运行的现有流程。这就是FastCGI的意义所在;它维护了一个与CGI非常相似的接口(你有一组包含大部分请求信息的变量,以及一个请求主体的数据流)。但是,它不是设置实际的Unix环境变量并在stdin上使用正文启动新进程,而是向已在机器上运行的FCGI服务器发送类似于HTTP请求的请求,其中它指定了这些变量的值,请求正文内容。

如果Web服务器可以以某种方式嵌入程序代码,这会变得更加高效,因为它只运行代码本身。有关如何执行此操作的两个典型示例是:

  • 将PHP嵌入到Apache中,以便“Apache服务器代码”只调用“PHP服务器代码”,这是同一过程的一部分;以及

  • 根本不运行Apache,但让Web服务器用Ruby(或Python,或其他)编写,并加载并运行更多自定义编写的Ruby代码来处理请求。

    < / LI>

那么Rack在哪里呢? Rack是一个 API ,它允许处理Web请求的代码以通用方式接收它,而不管Web服务器如何。因此,给定一些Ruby代码来处理使用Rack API的请求,Web服务器可能会:

  • 是一个Ruby Web服务器,只需在其自己的进程中对其加载的符合Rack的代码进行函数调用;
  • 是一个Web服务器(用任何语言编写),它使用FastCGI协议与另一个进程通过FastCGI服务器代码进行通信,该代码再次对符合Rack的代码进行函数调用以处理请求;或
  • 是一个服务器,它启动一个全新的过程,解释传递给它的CGI环境变量和标准输入,然后调用符合Rack的代码。

因此,无论您使用的是CGI,FastCGI,其他进程间协议还是进程内协议,都没有区别;只要服务器知道它或正在与可以理解CGI,FastCGI或其他任何内容的进程交谈并根据该请求调用符合Rack的代码,您就可以使用Rack进行任何操作。

所以:

对于性能扩展,您绝对不希望使用CGI;您希望使用FastCGI,类似的协议(例如Tomcat),或直接进行代码调用。

如果您使用Rack API,您不必担心在Web服务器和程序之间使用哪种协议的早期阶段,因为像Rack这样的API的全部内容是您可以在以后更改它。