最近项目中本地测试环境遇到了windows环境下的nginx使用file_get_contents/curl访问php文件致使的阻塞问题,一直在找解决的方案,这个问题研究了三天终于找到了解决方案,特别由于这个我也对php的运行原理产生了兴趣,因此这里对此进行必定程度的记录,可能会有错漏的地方,欢迎指正。php
要了解php的运行原理,首先要了解下面几个概念:前端
CGI:nginx
CGI的英文是(COMMON GATEWAY INTERFACE)公共网关接口,它的做用就是帮助服务器与语言通讯,这里就是nginx和php进行通讯,由于nginx和php的语言不通,所以须要一个沟通转换的过程,而CGI就是这个沟通的协议。web
nginx服务器在接受到浏览器传递过来的数据后,若是请求的是静态的页面或者图片等无需动态处理的则会直接根据请求的url找到其位置而后返回给浏览器,这里无需php参与,可是若是是一个动态的页面请求,这个时候nginx就必须与php通讯,这个时候就会须要用到cgi协议,将请求数据转换成php能理解的信息,而后php根据这些信息返回的信息也要经过cgi协议转换成nginx能够理解的信息,最后nginx接到这些信息再返回给浏览器。apache
fast-cgi:windows
传统的cgi协议在每次链接请求时,会开启一个进程进行处理,处理完毕会关闭该进程,所以下次链接,又要再次开启一个进程进行处理,所以有多少个链接就有多少个cgi进程,这也就是为何传统的cgi会显得缓慢的缘由,所以过多的进程会消耗资源和内存。浏览器
而fast-cgi则是一个进程能够处理多个请求,和上面的cgi协议彻底不同,cgi是一个进程只能处理一个请求,这样就会致使大量的cgi程序,所以会给服务器带来负担。服务器
php-cgi:markdown
php-cgi是php提供给web serve也就是http前端服务器的cgi协议接口程序,当每次接到http前端服务器的请求都会开启一个php-cgi进程进行处理,并且开启的php-cgi的过程当中会先要重载配置,数据结构以及初始化运行环境,若是更新了php配置,那么就须要重启php-cgi才能生效,例如phpstudy就是这种状况。数据结构
php-fpm:
php-fpm是php提供给web serve也就是http前端服务器的fastcgi协议接口程序,它不会像php-cgi同样每次链接都会从新开启一个进程,处理完请求又关闭这个进程,而是容许一个进程对多个链接进行处理,而不会当即关闭这个进程,而是会接着处理下一个链接。它能够说是php-cgi的一个管理程序,是对php-cgi的改进。
php-fpm会开启多个php-cgi程序,而且php-fpm常驻内存,每次web serve服务器发送链接过来的时候,php-fpm将链接信息分配给下面其中的一个子程序php-cgi进行处理,处理完毕这个php-cgi并不会关闭,而是继续等待下一个链接,这也是fast-cgi加速的原理,可是因为php-fpm是多进程的,而一个php-cgi基本消耗7-25M内存,所以若是链接过多就会致使内存消耗过大,引起一些问题,例如nginx里的502错误。
同时php-fpm还附带一些其余的功能:
例如平滑过渡配置更改,普通的php-cgi在每次更改配置后,须要从新启动才能初始化新的配置,而php-fpm是不须要,php-fpm分将新的链接发送给新的子程序php-cgi,这个时候加载的是新的配置,而原先正在运行的php-cgi仍是使用的原先的配置,等到这个链接后下一次链接的时候会使用新的配置初始化,这就是平滑过渡。
可能上面文字叙述很难理解,下面用图形来简要的说明浏览器请求web服务器的过程、cgi以及fastcgi,以及php-cgi和php-fpm之间的区别和联系:
上面是使用php-fpm的动态页面的过程,下面补充没有普通cgi协议的状况;
这里的web server能够是nginx,也能够是IIS和apache等http服务器,也能够成为网站服务器或者前端服务器。
原文地址:https://blog.csdn.net/belen_xue/article/details/65950658