【问题标题】:are zend engine globals share memory across processes?zend 引擎全局变量是否跨进程共享内存?
【发布时间】:2012-12-11 00:00:08
【问题描述】:

我一直在查看 PHP's source code and the mysql_pconnect function 并注意到它使用了某种在 zend_globals 中定义的 HashTable persistent_list。

问题是,当 PHP 设置为 mod apache/fcgi 时,如何跨请求保留这些全局变量和变量。如果它是为每个请求生成的新 PHP 进程,则不应保留这些变量。

【问题讨论】:

  • 这仅适用于一个进程服务超过 1 个请求的情况,或者通过重用它,或者通过它有多个线程来服务多个请求。长期以来,apache 的 mod_php 一直是 php 的黄金标准 sapi,而 apache 的配置方式通常是一个进程服务多个 php 请求。

标签: php php-internals


【解决方案1】:

问题是,当 PHP 设置为 mod apache/fcgi 时,如何在请求中保留这些全局变量和变量。

作为 apache 模块,它们是共享的,因为 apache httpd 本身仍在运行。该运行进程产生了 PHP,并将在未来产生其他 PHP。由于子线程可以与它们的父线程相关联,因此它可以并且存储在父内存空间中。

作为 FCGI,只要二进制文件已经在运行,这在技术上是可行的,但是这还没有通过 FPM 实现。我还要说,它对 FCGI 也没有真正意义,因为它是每个脚本并且还涉及超时,因此与整个网络服务器相比,生命周期要短得多。

【讨论】:

  • 相同的文档指出 the connection to the SQL server will not be closed when the execution of the script ends,这意味着它以某种方式保留了请求之间的连接(以及因此 php 进程的实例)
  • +1 @Alex:连接根本不会跨进程保留。如果您使用 Apache 的 MPM 工作程序(这是最常见且性能最高的设置),它们会跨 线程 保存。当脚本结束时,thread 结束,但进程仍然存在。如果您改用 MPM prefork,则每个脚本都有自己的进程(而不是线程),并且持久连接不会跨脚本持续存在。 hakre 的回答不是很详细,但仍然是正确的。
  • 在 apache 2 之前,没有 apache worker mpm(多线程),只有 prefork(每个请求的进程),并且在那几天已经出现了 mysql_pconnect。那时谁在保持联系?
【解决方案2】:

PHP-FPM 重用上下文,允许持久连接在 FCGI 中工作。不过需要考虑的是 PHP-FPM 最初会创建多个进程,因此您最终仍会获得多个连接,每个进程或上下文一个连接。

需要考虑的是,“持久连接弊大于利”是#php.pecl 中经常提到的一句话。连接的开销很轻,PHP 适合这种处理。在设计为持续运行的语言中,连接的开销可能更大(通常是因为,简单的连接会影响比程序直接操作的对象更多的对象),因此持久连接或池连接是有意义的。 PHP 的设计目的是尽可能快地完成所有事情,而且它使用了多少资源来做这件事——一切都必须在大约 250 毫秒内运行——连接到 mysql 不会像在其他框架中那样触发一堆钩子语言,所以开销非常小。此外,每个进程的持久连接并不像其他语言那样构成托管连接池,如果接收机器没有配置它的 mysql 实例(具有荒谬的设置),那么连接将变得陈旧并且在 *_pconnect PHP 在创建新连接之前必须首先使旧连接无效,这比刚开始创建新连接效率低且速度慢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    相关资源
    最近更新 更多