简单谈谈PHP中的Reload操作

yipeiwu_com5年前PHP代码库

前言

有很多前辈告诫过我们,reload 能保证整个过程的平滑性,所谓平滑性指的是在 reload 的过程中,旧的进程在处理完当前请求前不会提前终止。很多年来,我从来没有质疑过这种说法,直到有一天,当我 reload 的时候,出现了 502 错误,让我不得不重新思考。

如何重现问题呢?让我们写一个简单的脚本来模拟:

<?php

sleep(11);
echo "foo";

?>

此时用浏览器浏览这个网址,接着立刻执行 reload 操作,就能看到 502 错误了。

难道 PHP 这么弱?连 reload 基本的平滑性都无法保证?答案当然是否定的,实际上通过 process_control_timeout 参数可以实现我们的目标。可惜这个参数缺省是 0,也就是不生效,本文把它设置成 10s。重新执行之前的实验步骤,这一次正常输出了结果。不过如果你多做几次实验的话,可能会发现当我们 reload 的时候,sleep 立刻就结束了,这是因为 sleep 收到 reload 发出的信号后直接返回了,下面让我们再改写一下脚本:

<?php

sleep(11);
echo "foo";
sleep(11);
echo "bar";

?>

重新执行之前的实验步骤,你会发现 502 错误又出现了。这是因为 reload 虽然让第一个 sleep 立刻结束了,但是第二个 sleep 还是有效的,而且超过了 process_control_timeout 的时间限制。如果我们把 process_control_timeout 设置为 12s,那么就又好了。

如此说来,我们只要给 process_control_timeout 设置一个合理的数值就能保证 reload 操作的平滑性,不过到底多大是合理的数值呢?太小的话可能起不到作用,太大的话会不会有副作用?让我们带着疑问重复上一次实验,不过这次我们再加一个监控:

shell> watch -n1 'ps aux | grep php[-]fpm'

此监控的目的是为了观察 reload 过程中 PHP-FPM 进程数的变化情况,为了让效果更明显些,建议把 PHP-FPM 的启动方式改成 static 模式,同时进程数不要太多。

当我们重复上一次实验的时候,结果发现除了正在执行请求的进程,其它进程直接就被干掉了,而新进程又没有立刻启动,就这样一直卡到最后一个旧进程执行完后新进程才完成启动过程。在此期间,如果有别的请求进来,那么无疑它无法立刻得到响应。

根据我们的实验可以得出结论:缺省情况下,PHP-FPM 无法保证平滑的执行 reload 操作,必须设置一个合理的 process_control_timeout 才行,同时需要注意的是其值不能设置的过大,否则系统可能出现更为严重的请求堵塞问题。

总结

以上就是关于PHP中Reload操作的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

相关文章

php二分法在IP地址查询中的应用

数据库大概存储几十万条IP记录,记录集如下: +----------+----------+------------+---------+---------+--------+-----...

php 修改、增加xml结点属性的实现代码

php 修改 增加xml结点属性的代码,供大家学习参考。php修改xml结点属性,增加xml结点属性的代码,有需要的朋友,参考下。 1、xml文件 复制代码 代码如下:<?xml...

PHP常见错误提示含义解释(实用!值得收藏)

本文讲述了PHP常见错误提示含义解释。分享给大家供大家参考,具体如下: 在学习PHP的时候,经常遇到各种错误提示,今天看到这错误提示和解释感觉挺好,现转过来,供我们学习。呵呵。。。。。...

PHP面向对象程序设计子类扩展父类(子类重新载入父类)操作详解

本文实例讲述了PHP面向对象程序设计子类扩展父类(子类重新载入父类)操作。分享给大家供大家参考,具体如下: 在PHP中,会遇到这样的情况,子类继承父类,但是又需要对父类的属性和方法进行一...

php面向对象中static静态属性与方法的内存位置分析

本文实例分析了php面向对象中static静态属性与方法的内存位置。分享给大家供大家参考。具体如下: static静态属性的内存位置——>类,而不是对象。下面做测试来证明一下...