IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

Lighttpd mod_fastcgi源码分析

idea's blog 2011-08-23 13:51:29 累计浏览 4,164 次
本机暂存

    最近在设计一种网络服务器架构, 最重要的一点是把耗时操作委托给工作进程(或者线程)来做, 所以考察一下 fastcgi. 大概看了下 lighttpd 的 mod_fastcgi 的源码, 没想到立即被卡住了. 根据我的想法, PHP 等 fastcgi 程序(php-cgi 进程)监听网络, 然后 mod_fastcgi 只需要 connect 这些进程即可, 奇怪的是, 我竟然看到了 listen! -

fcgi_spawn_connection() 函数:

fcgi_fd = socket(socket_type, SOCK_STREAM, 0);

if (-1 == connect(fcgi_fd, fcgi_addr, servlen)) {
    close(fcgi_fd);
    fcgi_fd = socket(socket_type, SOCK_STREAM, 0);
    /* create socket */
    bind(fcgi_fd, fcgi_addr, servlen);
    listen(fcgi_fd, 1024);

    switch ((child = fork())) {
    case 0: {
        // child process
        if(fcgi_fd != FCGI_LISTENSOCK_FILENO) {
            close(FCGI_LISTENSOCK_FILENO);
            dup2(fcgi_fd, FCGI_LISTENSOCK_FILENO);
            close(fcgi_fd);
        }
        /* exec the cgi */
        execve(arg.ptr[0], arg.ptr, env.ptr);
        exit(errno);
    }
}

    我很奇怪, mod_fastcgi 为什么要监听网络连接? 谁会连接它? 问了同事, 同事说可能是 fastcgi 进程要连接它, 可问题是 fastcgi 进程怎么知道连接什么地方, 更不用说, fastcgi 协议里没有提到要 fastcgi 进程主动连接 Web Server 一说.

    再看一遍代码, 我注意到了 dup2() 调用, 会不会是 lighttpd 为 php-cgi 进程创建了一个监听 socket? 于是看了下 PHP fastcgi 的代码, 如下解析命令行参数的一段:

\"  -b | Bind Path for external FASTCGI Server mode\\\\n\"
/* if we\\\'re started on command line, check to see if
   we are being started as an \\\'external\\\' fastcgi
   server by accepting a bindpath parameter. */
case \\\'b\\\':
...
if (bindpath) {
    fcgi_fd = fcgi_listen(bindpath, 128);
}

    也就是说, 如果指定了 -b 选项, php-cgi 就会创建监听进程, 如果没有的话, fcgi_fd 就是默认的 0(标准输入的文件描述符), 也就是 FCGI_LISTENSOCK_FILENO.

    所以, lighttpd mod_fastcgi 的逻辑是这样, 如果需要 spawn php-cgi 进程, 它会创建一个监听的 socket, 然后把该 socket dup2 到 标准输入的 fd, 接着 fork 并用 execve() 函数执行 php-cgi 程序, 这样, php-cgi 程序就可以使用该监听 socket 来接受 mod_fastcgi 的网络连接了.

    只要知道了这个逻辑, 细节问题不必深究.

同分类推荐文章

  1. 等了十年的 Go 链式管道,终于来了:seq 让你像写 Scala 一样写 Go (2026-06-25 18:38:18)
  2. Go 实验特性详解 (2026-06-21 10:05:27)
  3. amd64 微架构级别对 Go 程序性能提升多少? (2026-06-21 09:38:49)

查看更多 后端 文章 →

建议继续学习

  1. 使用gettext来支持PHP的多语言 (累计阅读 39,269)
  2. WordPress插件开发 -- 在插件使用数据库存储数据 (累计阅读 29,164)
  3. Paypal接口详细代码(PHP版,非API接口) (累计阅读 19,408)
  4. 我的PHP,Python和Ruby之路 (累计阅读 13,147)
  5. include(“./file.php”)和include(“file.php”)区别 (累计阅读 12,789)
  6. 15个最好的免费开源电子商务平台 (累计阅读 12,541)
  7. Redis消息队列的若干实现方式 (累计阅读 12,088)
  8. 到底什么是MVC? (累计阅读 11,865)
  9. 整理了一份招PHP高级工程师的面试题 (累计阅读 11,708)
  10. Rolling cURL: PHP并发最佳实践 (累计阅读 11,488)