首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么要避免使用CGI?

为什么要避免使用CGI?
EN

Stack Overflow用户
提问于 2013-04-18 10:51:05
回答 3查看 208关注 0票数 1

我试着用CGI和ERB创建我的网站,但当我在网上搜索时,我发现人们说我应该总是避免使用CGI,总是使用Rack

我知道CGI会派生很多Ruby进程,但是如果我使用FastCGI,只会创建一个持久化进程,它也被PHP网站采用。此外,FastCGI接口只为一个请求创建一个对象,并且具有非常好的性能,而Rack则一次创建7个对象。

有什么特别的原因让我不能使用CGI吗?或者这只是一个错误的假设,完全可以使用CGI/FastCGI?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-04-18 12:37:00

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

这在当时是最先进的,当时还没有我们今天所认为的真正的"web框架“和”嵌入式服务器模块“。因此...

CGI往往很慢

同样,CGI模型为每个连接生成一个新进程。虽然现在生成进程本身很便宜,但繁重的web应用程序初始化-读取和解析大量模块,建立数据库连接等-使得这变得相当昂贵。

CGI倾向于太低级(IMHO)设计

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

与Rack::Builder之类的东西形成对比,在Rack::Builder中,编码器立即考虑将名称空间映射到操作,以及这对更广泛的web应用程序意味着什么。(突然之间,我们可以自由地讨论语义网和REST之类的优点,因为我们不会考虑根据用户提供的输入生成单选按钮。)

是的,像Rack::Builder这样的东西可以在CGI之上实现,但这就是重点。它必须是一个建立在CGI之上的抽象层。

CGI倾向于被冷落。

尽管CGI在其限制范围内工作得很好,尽管它很简单并且被广泛理解,但CGI经常被轻率地抛弃。如果CGI是你所知道的全部,你也可能会被解雇。

票数 1
EN

Stack Overflow用户

发布于 2013-04-18 11:09:41

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

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

Rack是一个更好的系统,它工作得非常好。如果你使用Rack,你有各种各样的主机系统可供选择,甚至包括Passenger,它非常简单和可靠。

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

我想不出有哪一个实例的CGI会比Rack等效物更好。

票数 1
EN

Stack Overflow用户

发布于 2016-10-05 01:38:48

对于CGI、Rack等到底是什么存在很多困惑。正如我所描述的,Rack是一种here,而FastCGI是一种协议。CGI也是一种协议,但在狭义上也是一种实现,对于你所说的与FastCGI完全不是一回事。因此,让我们从背景开始。

回到90年代早期,web服务器只是从磁盘上读取文件(HTML、图像等),然后将它们发送到客户端。在请求的时候,人们开始想要做一些处理,早期的解决方案是运行一个程序,该程序将产生发送回客户端的结果,而不仅仅是读取文件。这样做的“协议”是给予web服务器一个URL,该URL被配置为作为程序(例如,/cgi-bin/my-script)执行,其中web服务器随后将设置一组具有关于请求的各种信息的环境变量,并在标准输入上运行具有请求主体的程序。这被称为“Common Gateway Interface”。

考虑到这会为每个请求派生一个新的进程,这显然是低效的,而且几乎可以肯定的是,您不希望在大容量网站上使用这种动态请求处理方式。(启动一个全新的进程在计算资源上相对昂贵。)

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

如果web服务器能够以某种方式将程序代码嵌入其中,这将变得更加高效,因为它只需运行代码本身。关于如何做到这一点,有两个经典的例子:

  • 将PHP嵌入到Apache中,因此"Apache服务器代码“只调用"PHP服务器代码”,这是同一进程的一部分;而
  • 根本不运行Apache,而是使用ruby语言(或Python或其他语言)编写web服务器,并加载和运行更多为处理请求而定制的Ruby代码。

那么Rack在这方面有什么用处呢?Rack是一个应用程序接口,它让处理web请求的代码以一种通用的方式接收它,而不管web服务器是什么。因此,给定一些Ruby代码来处理使用Rack API的请求,web服务器可能会:

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

所以,无论你使用的是CGI、FastCGI、另一个进程间协议,还是进程内协议,都没有区别;只要服务器知道它,或者正在与一个可以理解CGI、FastCGI或任何东西的进程对话,并基于该请求调用符合Rack的代码,你就可以使用Rack执行任何这些操作。

所以:

对于性能扩展,您肯定不希望使用CGI;您希望使用FastCGI,一种类似的协议(比如Tomcat ),或者直接在进程内调用代码。

如果你使用Rack API,你不需要担心在你的web服务器和你的程序之间使用哪种协议,因为像Rack这样的API的全部要点是你可以在以后改变它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16073700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档