Redis连接方式pconnect和connect初步探索

总结一下最近比较杂乱的学习。


看到有人提PHP_EOL的作用,解释说是所有PHP环境下的空格,我刚好看到,因为PHP_EOL我经常在输出日志的时候用,非常了解作用,是用来兼容不同操作系统换行符的,避免犯错,我还是网上查找一番,确定无误后,我特意@了下,这个是换行符。虽然最后没相信我,大家可以试一下,甭管是百度还是必应更不要说是google,第一行出来的绝对就扣上了换行两个大字。最后他发了一段代码

浏览器的输出结果是10 10。中间确实有个空格,然而实际上,把PHP_EOL换成\n,浏览器显示的也会是个空格,只是作为一个未被解析的字符。

使用curl命令访问:

这个答案就够清晰了吧。

 

另外有人问set_exception_handler()和register_shutdown_function()有什么区别,为什么有了第一个还要有第二个。第一个函数顾名思义,就是设置异常处理函数,在exception抛出时,优先执行用户的自定义函数,这个我平时没用过。第二个函数我在看TP源码的时候有看到,后续在自己的项目代码里也用上了,用来注册逻辑代码执行完成后的执行函数,目前实现的比较简单,用来将保存在内存的日志输出、对资源进行释放等。

 Redis连接方式pconnect和connect初步探索_第1张图片

 

再聊聊最近在使用Redis的时候,发现有pconnect和connect两个连接函数,查找资料解释如下:

Redis连接方式pconnect和connect初步探索_第2张图片

Redis连接方式pconnect和connect初步探索_第3张图片

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连接方式pconnect和connect初步探索_第4张图片

在单个脚本执行时,尽管实例化多个redis对象,但是与redis构建的连接仅为1

Redis连接方式pconnect和connect初步探索_第5张图片

估计是类似如上的模型

 

验证发现一个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

执行脚本,

Redis连接方式pconnect和connect初步探索_第6张图片

在执行过程中,查看指定php-fpm进程存在一个redis客户端连接,执行完成后连接消失

 

打开redis.log,

这一部分涉及到其他相关知识,只做验证。

 Redis连接方式pconnect和connect初步探索_第7张图片

两处红框标注连接和关闭的部分。

 

pconnect('127.0.0.1', 11279);
$redis->auth('123456');
$redis->set('name', 'll1');
sleep(5);
$redis->close();
sleep(5);

换成pconnect后继续执行

Redis连接方式pconnect和connect初步探索_第8张图片

此时脚本已执行完成,php-fpm进程仍保留了和redis的连接

 Redis连接方式pconnect和connect初步探索_第9张图片

继续执行,如下图所示

Redis连接方式pconnect和connect初步探索_第10张图片

connect和close的操作都消失了,但是与redis的通信仍然存在。

从这方面来看,pconnect的所谓重用不关闭,体现的非常明显。




你可能感兴趣的:(PHP)