redis长连接pconnect分析

测试环境

Nginx + php-fpm + redis

Nginx配置

 

php-fpm配置

 

PHP代码

 


验证1:

1.  先查看 php-fpm 的唯一一个work进程的 进程ID

ps aux |grep php-fpm

进程ID为 30870

2.  打开2个终端

在终端1执行: strace -p30870 -s 1024 -o redis_1
-p 端口 -s 字符串长度 -o 输出 一次请求的系统调用到指定文件redis_1中
在 终端2执行: curl www.t.abc/index.php

3.  lsof -n -p 30870
可以看到,fpm进程仍然保有一个到10.136.30.144的reids连接,其文件描述符为9(这与strace的结果一致)

4.  打开2个终端

在终端1执行: strace -p30870 -s 1024 -o redis_2
-p 端口 -s 字符串长度 -o 输出 一次请求的系统调用到指定文件redis_1中
在 终端2执行: curl www.t.abc/index.php

 

5.  查看 redis_1 与 redis_2 文件
redis_1

执行结束后, 文件描述符 4 没有关闭

redis_2

没有再次进行 redis 连接,直接使用 文件描述符 4, 此次请求结束后, 关闭 (因为 php-fpm已经完成两次请求, 整个进程被关闭)

再次执行 lsof -n -p 30870
发现 没有显示任何数据, 因为 该 进程已经被关闭

结论:

当使用pconnect时,连接会被重用,连接的生命周期是fpm进程的生命周期,而非一次php的执行。。

 

验证2:

使用connect连接redis,并调用redis->close()的系统调用。(将上述代码中的pconnect改为connect, 同时在最后加入redis->close()

PHP代码

 

我们看到,除了建立连接外,在程序结尾,还向reids发送了quit命令,并关闭了连接的文件描述符

 

验证3:

php代码:

请求结束, 文件描述符 都没关闭

 

接着请求第二次, 该进程结束. 文件描述符才关闭

 

如果代码中使用pconnect, close的作用仅是使当前php不能再进行redis请求,但无法真正关闭redis长连接,连接在后续请求中仍然会被重用,直至fpm进程生命周期结束。

结论

1. 当使用pconnect时,连接会被重用,连接的生命周期是fpm进程的生命周期,而非一次php的执行。
2. 如果代码中使用pconnect, close的作用仅是使当前php不能再进行redis请求,但无法真正关闭redis长连接,连接在后续请求中仍然会被重用,直至fpm进程生命周期结束。

 

参考: http://www.cnblogs.com/huanxiyun/articles/6554670.html