总结一下最近比较杂乱的学习。
看到有人提PHP_EOL的作用,解释说是所有PHP环境下的空格,我刚好看到,因为PHP_EOL我经常在输出日志的时候用,非常了解作用,是用来兼容不同操作系统换行符的,避免犯错,我还是网上查找一番,确定无误后,我特意@了下,这个是换行符。虽然最后没相信我,大家可以试一下,甭管是百度还是必应更不要说是google,第一行出来的绝对就扣上了换行两个大字。最后他发了一段代码
浏览器的输出结果是10 10。中间确实有个空格,然而实际上,把PHP_EOL换成\n,浏览器显示的也会是个空格,只是作为一个未被解析的字符。
使用curl命令访问:
这个答案就够清晰了吧。
另外有人问set_exception_handler()和register_shutdown_function()有什么区别,为什么有了第一个还要有第二个。第一个函数顾名思义,就是设置异常处理函数,在exception抛出时,优先执行用户的自定义函数,这个我平时没用过。第二个函数我在看TP源码的时候有看到,后续在自己的项目代码里也用上了,用来注册逻辑代码执行完成后的执行函数,目前实现的比较简单,用来将保存在内存的日志输出、对资源进行释放等。
再聊聊最近在使用Redis的时候,发现有pconnect和connect两个连接函数,查找资料解释如下:
connect:创建一个Redis客户端
pconnect:创建一个Redis客户端或重用一个通过pconnect/popen已连接就绪的客户端
(调用close方法或请求结束,Redis连接不会被关闭,直到PHP进程结束)
服务器环境:apache2.4/PHP5.6,mod_php方式。
最先使用了connect方法
connect('127.0.0.1', 11279);
$redis->auth('123456');
$redis->incr('testKey');
运行前查看Redis的客户端连接数
使用apache-jmeter工具进行30并发请求
等待脚本执行完成
结论:connect连接方式在脚本执行完成后,即使不执行close方法,也会释放Redis连接。
改用pconnect方法测试
pconnect('127.0.0.1', 11279);
$redis->auth('123456');
$redis->incr('testKey');
发送请求
等待脚本执行完成
发现连接也全部释放掉了。
查找发现,pconnect方法连接不释放的前提是,仅针对php-fpm模式。
切换环境继续测试:
设置pm = static (避免进程自动增删影响)
pm.max_children = 30
请求中
等待脚本执行完成
脚本执行后发现30个php-fpm进程对应到30个redis客户端连接。
疑问:一个php-fpm进程会占用多个redis客户端连接数吗?
pconnect('127.0.0.1', 11279);
$redis1->auth('123456');
$redis2 = new Redis();
$redis2->pconnect('127.0.0.1', 11279);
$redis2->auth('123456');
if ($redis1 === $redis2) echo 'ok';
else echo 'no';
sleep(10);
设置pm.max_children = 1方便定位
执行一个脚本程序发现,echo内容为no,但是该进程连接数一直仅占用1
查看php-fpm进程详情
在单个脚本执行时,尽管实例化多个redis对象,但是与redis构建的连接仅为1
估计是类似如上的模型
验证发现一个php-fpm进程不会占用多个redis客户端连接数。
同时验证以下结论属实:
pconnect:创建一个Redis客户端或重用一个通过pconnect/popen已连接就绪的客户端
(调用close方法或请求结束,Redis连接不会被关闭,直到PHP进程结束)
即:进程会保留一个redis客户端连接重复使用
刚刚发现有一个strace命令:常用来跟踪进程执行时的系统调用和所接收的信号。
另外的文章里使用strace来追踪PHP-FPM进程与redis通信,可以比较直观体现两者通信细节,后续自己学习下补充~
模拟下从他处学习到的。
connect('127.0.0.1', 11279);
$redis->auth('123456');
$redis->set('name', 'll1');
sleep(5);
$redis->close();
sleep(5);
监控进程执行,
strace -p 2799 -o redis.log –t
执行脚本,
在执行过程中,查看指定php-fpm进程存在一个redis客户端连接,执行完成后连接消失
打开redis.log,
这一部分涉及到其他相关知识,只做验证。
两处红框标注连接和关闭的部分。
pconnect('127.0.0.1', 11279);
$redis->auth('123456');
$redis->set('name', 'll1');
sleep(5);
$redis->close();
sleep(5);
换成pconnect后继续执行
此时脚本已执行完成,php-fpm进程仍保留了和redis的连接
继续执行,如下图所示
connect和close的操作都消失了,但是与redis的通信仍然存在。
从这方面来看,pconnect的所谓重用不关闭,体现的非常明显。