在分析CGI协议的时候,发现其中可以深挖的东西很多,通过本文进行梳理

前置知识

Apache服务器和Tomcat服务器的区别与联系

先单独提一下Apache和Tomcat

Apache

Apache是C语言实现的,专门用来提供HTTP服务。

特性:简单、速度快、性能稳定、可配置(代理)

  • 主要用于解析静态文本,并发性能高,侧重于HTTP服务
  • 支持静态页(HTML),不支持动态请求如:CGI、Servlet/JSP、PHP、ASP等
  • 具有很强的可扩展性,可以通过插件支持PHP,还可以单向Apache连接Tomcat实现连通
  • Apache是世界使用排名第一的Web服务器

Tomcat

Tomcat是Java开发的一个符合JavaEE的Servlet规范的JSP服务器(Servlet容器),是 Apache 的扩展。

扩展,就是最初开发出来的目的是为了丰富Apache的功能。但注意,Tomcat也可以独立于Apache运行。

特性:免费的Java应用服务器

  • 主要用于解析JSP/Servlet,侧重于Servlet引擎
  • 支持静态页,但效率没有Apache高;支持Servlet、JSP请求
  • Tomcat本身也内置了一个HTTP服务器用于支持静态内容,可以通过Tomcat的配置管理工具实现与Apache整合

区别与联系

image-20240405200003092

Apache + Tomcat集成(即Java Web)使用的处理逻辑我这里提一下,如果请求是静态网页则由Apache处理,并将结果返回;如果是动态请求,Apache会将解析工作转发给Tomcat处理,Tomcat处理后将结果通过Apache返回。这样可以达到分工合作,实现负载远衡,提高系统的性能。

为了便于理解,我总结一下:

  • Apache是Web服务器,而Tomcat是Web应用服务器(或者说Java应用服务器)

    image-20240405200957262

    image-20240405201043634

  • Apache服务器只处理静态页面,Tomcat服务器静态页面、动态页面都能处理。所以一般把Apache服务器与 Tomcat服务器搭配在一起用,即Apache服务器负责处理所有静态的页面/图片等信息,Tomcat只处理动态的部分

浏览器处理静态/动态网页过程

众所周知,在网站分类中存在一种分类就是静态网站和动态网站,两者的区别就是静态网站只需要通过浏览器进行解析,其中的页面是一对一的(一个内容对应一个页面),而动态网站需要一个额外的编译解析的过程,网页上的数据是从数据库中或者其他地方调用,页面会随着数据的变化而改变,就产生了一定的交互性。

浏览器访问静态网页过程

在整个网页的访问过程中,Web服务器(例如Apache)只担任着内容分发者的身份,当访问静态网站的主页时,Web服务器会到网站的相应目录中查找主页文件,然后发送给用户的浏览器。具体逻辑如下:

image-20240405203426501

浏览器访问动态网页过程

以 Apache + PHP 构建的动态网页(即PHP Web)为例。

当访问动态网站的主页时,根据容器的配置文件,它知道这个页面不是静态页面,Web服务器就会去找PHP解析器来进行处理(上面介绍Apache的时候提到过,Apache具有很强的可扩展性,可以通过插件支持PHP),它会把这个请求进行简单的处理,然后交给PHP解释器。逻辑图如下:image-20240405203621002

当Apache收到用户对 index.php 的请求后,如果使用的是CGI,会启动对应的 CGI 程序,对应在这里就是PHP的解析器。接下来PHP解析器会解析php.ini文件,初始化执行环境,然后处理请求,再以CGI规定的格式返回处理后的结果,退出进程,Web服务器(也就是这里的Apache)再把结果返回给浏览器。这就是一个完整的动态PHP Web访问流程。

这里约定一下:解析器 = 解释器,是同一个意思。

CGI技术

通过上面的两个例子(即Java Web和PHP Web),可以看出实现动态网页有不同的方式:

  • Web服务器 + Web应用服务器,如:Apache + Tomcat
  • Web服务器 + CGI,如:Apache + PHP解析器

这里讨论CGI技术。

image-20240405205418078

上面提到了,CGI 即 Common Gateway Interface,译作“通用网关接口”,我们对其逐词拆解:

  • Common,即通用,理论上来说,所有支持标准输入、标准输出、获取环境变量的编程语言都能用来编写CGI程序(所以,几乎所有的编程语言都能编写CGI脚本,如Perl、Java、Python、C、shell等)

    还是做一个约定,CGI脚本 = CGI程序,是一个意思。

    再扩展一个冷知识,第一个版本的CGI由Perl语言编写的脚本。

  • Gateway,即网关,网关一词更多的是硬件层面的概念,但其实与CGI的网关二字之含义也是不谋而合的。称CGI为软件网关也不为过,因为Web服务器通过CGI与运行在其上的应用程序进行“交流”

  • Interface,即接口,这里更适合的应该称为接口协议,上面提到过,CGI是Web服务器和运行在其上的应用程序进行“交流”的一种约定,所谓的约定,就是以协议的形式实现。

所以,CGI不是一门编程语言,它是一种通信协议,协议也就是一种标准、一种约定。Web服务器按照约定向CGI程序发送数据,CGI程序按照约定返回数据。

CGI程序通常部署到Web服务器(如Apache)上,由Web服务器调用CGI程序。所以这里为了避免对上面的逻辑图产生歧义,我对其进行标注,如下:

image-20240405212614231

为满足不同的需求,自然可以部署多个CGI脚本,当收到一个匹配URL的请求,相应的CGI脚本就会被调用

image-20240405215324404

PHP-CGI

CGI是一个协议,PHP语言对CGI接口规范的实现也就是PHP-CGI,也就是PHP的解释器。

FastCGI技术

FastCGI就相当于高性能的CGI,与CGI不同的是,它像一个常驻的CGI,在启动后会一直运行着,不需要每次处理数据时都启动一次, 所以这里引出下面这句概念,FastCGI是语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解释器进程保持在内存中,并因此获得较高的性能 。

image-20240405214242636

PHP-FPM

FastCGI是一个协议,PHP-FPM实现了这个协议。FastCGI是CGI的改进版,它是一个常驻内存的CGI服务。常用的PHP-FPM就是在这种模式下运行的,PHP-FPM负责Fork多个进程,每个进程都运行着PHP解释器。

鸣谢

Comments

2024-04-05

⬆︎TOP