首先我们要了解一个概念cgi,cgi (comman gateway interface),从名字看这是一个接口。
以前服务端主要用来和网页端做交互,我们通常叫网页端为web端,服务端叫web服务器,web我们有静态网页和动态网页。静态网页就是纯html编写,web端请求服务器时,服务器只需要下发静态html就可以让前端展示出来。但是后来有了动态网页技术,比如我们的一个个人信息页面,我们需要根据不同的用户取到不同的用户信息,填入到我们的html中,再进行展示,所以传统的静态网页已经不能满足,我们需要动态的生成网页,这就是动态技术要解决的问题和原始想法。
有了想法,总要落地吧,要请求还要有输出,那我们基本就需要一个请求,和一个响应,何时请求呢,我们可以在html中插入我们需要进行请求的代码,比如php脚本。我们要去请求一个数据库,从数据库拿到数据来进行响应。那么问题来了,每个不同的语言如果都实现一套自己的方案,那样第三方的软件适配起来就会很头疼,总要一个标准吧,这就是cgi要解决的问题。cgi是在web前端和数据端中间的一套适配接口。
接下来每个语言现在可以按照cgi的要求来实现自己版本的cgi了,php就诞生了php-cgi,php-cgi可以解析php脚本,从里面提取任务,来完成对数据的请求。能解析php脚本,我们通常也称为php解释器。
问题是解决了功能问题,就遇到了性能瓶颈。传统的调用php-cgi的方式,收到一个请求,那么服务器就开启一个进程来初始化php-cgi,这里会加载我们的php环境,框架,还有我们想要的php脚本。等任务结束了,我们会退出这个进程。请求量不大还好,但我们在请求量稍大的时候,也在不停的创建进程,退出进程,这就造成了资源的浪费。于是有人就提出了Fast-cgi的想法。
fast-cgi是对cgi的改进。fast-cgi使用了常驻进程的方式。我们可以理解为维护了一个进程池。当我们请求时候,我们会优先从进程池中取得空闲进程,来进行任务的响应,当任务结束时候,我们并不需要退出进程,而是它会作为一个空闲进程在进程池中继续等待下一个请求。
关于进程和线程,进程是资源管理的最小单位,线程是程序运行的最小单位。当我们运行一个程序时,我们需要进程来维护程序需要使用到的资源,存储空间,同时为了代码可以运行,我们需要至少一个线程。
(我的另一个理解是进程是在空间维度上,线程是在时间维度上。我们需要进程来申请空间,我们需要线程来申请运行时间。所以多进程要比多线程要成本高,因为多进程我们需要申请一个新的空间,而多线程只是运行时间的再次分配。)
Phpfpm就是fast-cgi在php中的一个实现。实现fast-cgi的一个主要工作就是管理和调度进程池中的进程。不过这里要特别注意常驻进程池中的是php解释器。并且再次强调fast-cgi要解决的问题是进程的反复创建和释放。这有利于理解后面swoole进行的优化。“常驻进程池中的是php解释器”这句话怎么理解呢,首先我们的php解释器不用重新创建了,其次当我们收到请求的时候,我们需要根据收到的php脚本,从头来一遍解析,去初始化相应的php环境,全局变量,方法调用等等。想想,每次都初始化一遍环境,就像如果是编译型语言,每次调用都得重新编译一遍一样。这就是后面swoole来进行的改进。
swoole在第一次初始化的时候就会对工程进行一遍全局初始化,当我们请求的时候,swoole直接使用缓存的环境数据。从而避免了环境的反复初始化和释放。
更多的我也讲不出来了。
网友评论