最近发现php-cgi经常崩溃的问题,在网上搜了一下发现spawn-fcgi是个不错的选择用来处理该问题。据说该软件是从lighttpd中的模块分离出来的,代码比较少只有500多行的样子,看了下代码也比较简单,工作流程也比较简单,但是比较迷惑。
整体流程就是根据参数建立socket连接,有两种选择(AF_UNIX,AF_INET),然后bind,listen。接着是fork,父进程waitpid,子进程把socket dup2到标准输入,然手执行execv()参数应该是php-cgi。
很郁闷的是没找到accept的,后来搜了一下原来是对其工作原理不熟悉,原理如下图
看了一下php的源码,在cgi_main.c中的代码
int fcgi_fd = 0;
……
if(bindpath){
fcgi_fd = fcgi_listen(bindpath,128);
……
}
……
while( !fastcgi || fcgi_accept_request(&request) >= 0 ){
……
}
php-cgi的两种模式fastcgi模式和普通cgi模式,判断是不是fastcgi模式的方式就是判断fcgi_fd这个描述符是否有对端,也就是是否是有链接,如果有就是fastcgi模式
1)其中char * bindpath = NULL 只有在php-cgi指定参数-b的时候才会赋值也就是说:
php-cgi -b 127.0.0.1:9000 |
使用这种参数的时候php-cgi会自己创建完整的连接,因此肯定fastcgi模式(socket bind listen accept read)
2)而在普通fastcgi模式下,php-cgi自己直接accept fcgi_fd描述符(此时的fcgi_fd实际上就是被dup2后的标准输入),然后read
3)在cgi模式,php-cgi直接read标准输入