nginx与php通信机制

        前阵子读yii源码,发现访问的路由最终是通过php预定义变量$_SERVER拿到的,就比较好奇$_SERVER又是怎么拿到的呢?这就涉及到web服务器与php的通信机制了,由于我这里的web服务器是nginx,这里就看nginx与php的通信机制了。

       要研究这个问题,就得先了解一个概念:CGI协议。

1.CGI协议

       我们知道,web服务器只能处理静态内容,如果想处理动态内容,就要依赖web应用程序,如php、perl等。但web服务器如何将这些请求传递给对应的应用程序呢?这就得依赖CGI协议了,CGI协议和HTTP协议一样,也是一个处于应用层协议,目的就是解决web服务器和应用之间的通信问题。

        当用户访问我们的web应用时,会发起一个http请求,web服务器继而就会接收到这个请求;然后创建一个CGI进程,将http请求数据以一定格式解析出来,读取到环境变量中,并通过标准输入传到url指定的CGI程序,如php中的$_SERVER中;web应用程序处理完请求将数据写入标准输出中,web服务器进程再从标准输出中读取响应,并采用http协议返回给用户;最后web服务器关闭这个CGI进程。

        从这可以看出,CGI协议虽然可以解决web服务器和web应用之间的通信问题,但性能比较低下。因为每次处理用户请求时,都要新fork CGI子进程,处理完后还要销毁该进程;以及一系列的I/O开销降低了网络的吞吐量,造成资源浪费。这就引出了优化版FastCGI协议。

2.FastCGI协议

        从功能上讲,FastCGI协议和CGI协议是一样的,都是为了解决web服务器和web应用程序之间的通信问题,但是FastCGI协议是采用进程间通信来处理用户的请求的。

        FastCGI进程管理器启动时会创建一个master进程和多个worker进程,然后等待web服务器的连接;web服务器接收到http请求后,将CGI报文通过socket通信,将环境变量和请求数据写入标准输入,并转发到CGI解释器进程;CGI解释器进程处理请求后,将标准输出从同一连接返回给web服务器;此时CGI进程并不关闭,而是等待下一个http请求的到来。

        到这里,两种协议就基本介绍完了,但是还有一点,nginx并不能直接和FastCGI服务器进行通信,而是通过启用ngx_http_fastcgi_module模块进行代理配置,才能将请求发给FastCGI服务。其中包括常见的两个配置指令:

fastcgi_pass:设置FastCGI服务器监听的ip地址
fastcgi_param:处理映射关系,将nginx中的配置参数翻译成php能够理解的变量。

3.php-fpm

        CGI和FastCGI终究只是协议,还得依赖实现。php其实只是一个脚本解析器,可以理解为一个普通的函数,输入是php脚本,输出是执行结果。假如我们想用php代替shell,在命令行中执行一个文件,那么就可以写一个程序来嵌入php解析器,这就是cli模式。但如果让php处理http请求呢?这就涉及到网络处理了。php需要接受请求、解析http协议、处理请求并返回等,但php并没有像golang那样实现http网络库,而是实现了FastCGI协议,也就是php-fpm,和web服务器配合实现了http的处理。

        准确地说,php-fpm是一个fastcgi协议解析器,nginx处理http请求,将解析结果按照fastcgi协议打包好通过tcp传给php-fpm,然后php-fpm就按照fastcgi协议将tcp流解析成真正的数据。

        php-fpm核心功能是进程管理。概括来说,php-fpm的实现就是创建一个master进程,在master进程中创建socket并监听,然后fork多个子进程。各个子进程在启动后就阻塞在accept上,当请求到达后master进程指派其中一个worker进程读取请求数据并进行处理,之后再返回。子进程在处理期间不再接受其它请求,一次只能响应一个请求,只有把当前请求处理完成后才会accept下一个请求。另外php-fpm的master进程和worker进程之间不会进行直接通信,master进程是通过共享内存来获取worker进程的信息,比如worker进程当前状态、已处理请求数等,当master进程要kill一个worker进程时,也是通过发送信号方式通知worker进程。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值