今天在研究Nginx和PHP的通信原理,记录下作为自己的学习笔记。
首先来简单说一下,当访问我的blog时,访问的请求怎么在我的服务器上通信的:
这里我们看到nginx收到请求后,通过socket把不同进程间的数据通过FastCGI协议发送给相应的php-cgi进程,然后执行相应的操作。
CGI我们知道是通用网关协议,当webserver要访问PHP文件时,就要找PHP解析器来处理,但是nginx要传哪些参数给解析器,就是CGI来规定的,然后解析器还要去解析php.ini文件,进行初始化,然后处理请求,再以CGI规定的格式返回处理结果给webserver。
FastCGI则是一个常驻(long-live)的CGI,只有在启动初始化时,解析一次php.ini,初始化环境,提升效率。
php-cgi进程则是被php-fpm管理的对象,php-fpm全称为PHP FastCGI Process Manager,即php-fpm会根据用户配置来管理一批fastcgi进程,比如重启补全等,而真正衔接PHP和Nginx的则是fastcgi进程。
Nginx 作为我们常用的Webserver,以我的blog为例,我们看看是如何设置的。
我这里的socket采用的unix domain socket,因为nginx和php-fpm是在同一台服务器上,所以用本地套接字即可。
socket套接字主要有两种类型:unix domain socket和internet domain socket两种类型,简单说下他们的区别:
unix domain socket是进程间通信套接字,用于同一台主机上不同进程间交换数据。
intetnet domain socket网络套字节,是基于TCP/IP网络间的通信,nginx和php-fpm可以在不同的服务器上。也可以用于一台服务器,地址为本地127.0.0.1即可。
unix domain sokcket是用于同一台主机,不需要经过网络协议栈,不需要打包拆包、计算校验、维护应答等,只是将应用层数据从一个进程复制到另外一个进程,所以效率更快。而且不是用IP和端口表,是直接使用系统文件的地址来作为自己的身份,如上图所示。由于是在本机通过内核通信,不会丢包也不会出现发包次序和接收包次序不一致的问题。