CGI、FastCGI、FPM等概念梳理

总是在说Node.js是可以单线程异步IO、非阻塞、事件驱动等优点,但是对于其他方法还比较陌生,只停留在偶尔听过名词的概念,看到一篇文章很好的梳理了这些概念:

原文:http://jolestar.com/serverless-faas-current-status-and-future/

没有互联网的时候,应用程序多是单机命令行软件。当互联网出现的时候,有了将应用程序通过网络给其他人提供服务的需求。于是出现了 CGI (Common Gateway Interface),就是把命令行软件执行的结果通过网络输出。当时的应用程序的架构比较简单,启个 web 服务器监听网络端口,然后根据请求调用 CGI 程序,同时把请求数据传递给 CGI 程序,等待程序执行后把输出结果通过网络端口返回给客户端(一般是浏览器)。这种架构下,只有 web 服务器是常驻运行的,后面的 CGI 程序都是按需运行的,运行后就释放资源。于是诞生了一批支持 CGI 协议的脚本语言,比如 perl,php,asp,一方面脚本语言可以粘结 web 服务器和应用程序,另外一方面它本身也可以包含逻辑,于是逐渐出现专门针对 web 的用脚本编写的应用。

这种方式的优势很明显,按需运算,没有调用就几乎没有资源占用,一台机器就能托管大量的中小网站,运维成本也小,只需限制下 CGI 进程的执行时长和内存占用量就行,不用担心有人写了个死循环把整个服务器搞挂。所以最早的 php/asp 等脚本代码托管服务是按照空间计费的,可以理解成早期的『云』计算。

但缺点也很明显,每次调用都独立运行一个进程,如果并发量大,进程管理的资源浪费严重,随着互联网的发展出现了叫做 FastCGI 的技术。这种技术的思路是执行逻辑的进程不再是按需运行,而是常驻方式,web 服务器和 FastCGI 服务之间通过 unix socket 或者 tcp 进行交互。以 php-fpm(FastCGI Process Manager) 为例,php-fpm 启动一个常驻的进程池,每个请求分配给一个进程,进程调用 php 脚本执行后释放资源。当然这种方式带来的另外一个问题是常驻进程很容易产生内存泄露等问题,于是 php-fpm 提供一个选项可以设置执行多少次后重启进程。

如果单纯为了性能考虑,直接把应用程序打包到 web 服务器里,通过 web 服务器调用应该性能更好。但这样更新应用就需要同时更新 web 服务器,开发和维护成本比较高,而 web 服务器和应用程序一般是不同的提供方提供,多个应用程序共享同一台机器也会导致端口冲突。

同时期出现的技术还有 Java EE,提供了另外一种解决思路。Java EE 提供了一种叫做应用服务器或者 web container 的服务器软件,提供 web 服务器的功能,应用按照 Java EE 的规范暴露入口方法,然后打包成独立的发布包,部署到应用服务器中。应用服务器动态将应用加载到内存,相当于以动态方式把 web 服务器和应用程序合并成同一个程序,同时通过多线程而不是多进程来解决并发问题。这种方式兼顾了性能和应用独立发布的需求,同时依托应用服务器可以支持更多特性,所以 Java EE 能广泛占据企业端的市场。

于是 Java EE 厂商坐着火车吃着火锅,一路奔向应用标准化的未来。接连推出各种应用规范,想把应用功能通过规范沉淀到 Java EE 应用服务器中。但这时候互联网服务公司异军突起,打破了企业厂商的盛宴。互联网服务的特点是一个服务给全球人使用,对可移植性和标准化并没那么热衷,但对并发以及性能的要求极高,Java EE 中的特性也没几个能满足这种需求,于是宁愿从头打造工具和组件。

互联网高速发展了 10 多年后,大家开始思考,有没有一种应用的架构方式,即可以满足初期的快速研发需求,也可以承载后期的用户规模,还可以将应用的标准化功能沉淀到平台上独立提供?于是有了微服务,于是有了 FaaS。

文章原始链接:https://sijie.wang/posts/cgi-fpm/

本站文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请保留原始链接