深入php redis pconnect
深入php redis pconnect
pconnect是phpredis中用于client连接server的api。
API文档中的一句原文:
The connection will not be closed on close or end of request until the php process ends.
那么问题来了:
1.php process ends是指一次php执行完结,还是fpm的终结?如果是后者,那意味着即使一次php执行完毕,redis连接也不会被释放,下一次执行时redis连接会被重用。
2.The connection will not be closed on close是 说如果使用了pconnect, 即使在代码中显示的调用close(), 也不会关闭连接?
带着这两个问题,我们做下实验,深入看一下pconnect究竟做了些什么。
准备工作
环境:
nginx + fpm
php5.3
我们将fpm配置为
pm.max_children =1
pm.start_servers =1
pm.max_spare_servers =1
这样,我们的页面请求会由一个确定的fpm进程执行,方便strace跟踪。
对应页面请求的php代码:
$ip="10.136.30.144";
$port=7777;
$redis=newRedis();
$redis->pconnect($ip,$port,1);
$key="test";
$value="this is test";
$redis->set($key,$value);
$d=$redis->get($key);
var_dump($d);
代码的功能很简单,连接redis,先设置一个值,再取出。
测试问题一
思路:
使用strace观察fpm的系统调用,如果连接的生命周期是一次php执行,那么每次页面调用,都会有connect系统调用,用以连接redis;如果连接的生命周期是fpm的终结,那么只有第一次页面调用会有connect系统调用 ,之后由于连接被重用,无需connect,直接发命令请求即可。
启动一个新的fpm(进程号28082)。
执行
strace -p 28082 -s 1024 -o redis_1
可以看到进程先建立了socket连接(文件描述符为9)。然后给reids发一系列命令,最终取到“this is test”的结果串。且没有关闭连接相关的redis命令或系统调用。
页面请求结束后,我们执行
lsof -n -p 28082
可以看到,fpm进程仍然保有一个到10.136.30.144的reids连接,其文件描述符为9(这与strace的结果一致)。
执行
strace -p 28082 -s 1024 -o redis_2
与第一次请求的区别是:省去了建立连接的过程,直接发送reids命令,得到结果!
再使用lsof -n -p 28082查看fpm打开的文件描述符,结果与上文件相同。
说明,连接的确是被重用的,没有新建。
执行第6次页面请求(因为我们在准备工作中的配置,此时fpm已经是一个新的进程了),用lsof查看进程打开的文件描述符。
我们发现,虽然仍然有描述符为9的reids连接,但两个tcp连接的临时端口不同了,也就是连接改变了!
至此,我们得出问题1的结论:
当使用pconnect时,连接会被重用,连接的生命周期是fpm进程的生命周期,而非一次php的执行。。
测试问题二
为了对比,我们先看一下,使用connect连接redis,并调用redis->close()的系统调用。(将上述代码中的pconnect改为connect, 同时在最后加入redis->close())
我们看到,除了建立连接外,在程序结尾,还向reids发送了quit命令,并关闭了连接的文件描述符。
接下来,我们看在使用pconnect后,redis->close()有何表现
代码调整为:
$ip="10.136.30.144";
$port=7777;
$redis=newRedis();
$redis->pconnect($ip,$port,1);
$key="test";
$value="this is test";
$redis->set($key,$value);
$d=$redis->get($key);
var_dump($d);
$redis->close();
$redis->get($key);
我们直接看第2次执行页面请求的系统调用
并没有建立连接,同样是直接发送命令得到结果。说明连接被重用。同时,没有向reids server发送quit命令,也无关闭连接的系统调用。
至此,我们得出问题2的结论:
如果代码中使用pconnect, close的作用仅是使当前php不能再进行redis请求,但无法真正关闭redis长连接,连接在后续请求中仍然会被重用,直至fpm进程生命周期结束。
结论
1. 当使用pconnect时,连接会被重用,连接的生命周期是fpm进程的生命周期,而非一次php的执行。
2.如果代码中使用pconnect, close的作用仅是使当前php不能再进行redis请求,但无法真正关闭redis长连接,连接在后续请求中仍然会被重用,直至fpm进程生命周期结束。
深入php redis pconnect的更多相关文章
- 微擎开启redis memcache文档2
微擎开启redis memcache 2018年01月20日 14:39:54 luogan129 阅读数:2161更多 个人分类: 微信开发 版权声明:本文为博主原创文章,未经博主允许不得转载. ...
- 微擎开启redis memcache
微擎开启redis memcache 2018年01月20日 14:39:54 luogan129 阅读数:2161更多 个人分类: 微信开发 版权声明:本文为博主原创文章,未经博主允许不得转载. ...
- 使用99元一年的256MB高性能阿里云Redis加速Discuz论坛
介绍 Discuz是一个常见的论坛,支持使用Redis来对论坛进行加速访问,对于访问量比较大的论坛能够取到很好的作用,本文介绍如何使用阿里云高性价比256MBRedis来加速该论坛. 阿里云Redis ...
- centos8平台php7.4.2安装phpredis实现对redis的访问
一,下载phpredis 1,官方下载地址: https://github.com/phpredis/phpredis/releases 2,wget下载 [root@yjweb source]# w ...
- Discuz论坛提速优化技巧
Discuz是国内最受站长们欢迎的建站源码之一,除了开源以外还有着很强大的后台,即便是没有建站基础和不懂代码的站长也能很快的架设出一个论坛,甚至是门户. 一个网站的加载速度除了影响你在搜索引擎里的排名 ...
- discuz config_global.php文件设置说明
<?php $_config = array(); // ---------------------------- CONFIG DB ----------------------------- ...
- 弄技术要弄通-公司reis的pub/sub怎么使用的呢?
Pub/Sub in Redis using PHP Posted on November 14, 2011by xmeng I would like to put an example togeth ...
- IIS部署php项目——discuz论坛
1.安装CgiModule模块 首先,IIS要部署php项目,需要CgiModule模块的支持,所以首先我们要确认这个模块是否存在 打开IIS管理器: 我这里是存在的: 如果不存在,可以自行在控制面板 ...
- Redis中connect与pconnect区别?
1.首先先介绍下connect和pconnect的区别. connect:脚本结束之后连接就释放了. 2.pconnect:脚本结束之后连接不释放,连接保持在php-fpm进程中. 所以使用pconn ...
随机推荐
- pxc wsrep_sst_method均配置为xtrabackup-v2报错
启动第二节点报错:WSREP_SST: [ERROR] Error while getting data from donor node: exit codes: 137 0 本来所有节点的wsrep ...
- 更好的利用配置文件和importlib
需求:做不同的操作时只需修改配置文件即可完成 # message/email.py from .base import Base # 子类必须实现send方法,否则抛出异常 class Email(B ...
- centos设置代理上网
centos设置代理上网 假设我们要设置代理为 IP:PORT 1.网页上网 网页上网设置代理很简单,在firefox浏览器下 Edit-->>Preferences-->> ...
- C# static的用法详解
C# static的用法详解 有的东西你天天在用,但未必就代表你真正了解它,正如我之前所了解的 static . 一.静态类 静态类与非静态类的重要区别在于静态类不能实例化,也就是说,不能使用 n ...
- Java 动态代理是基于什么原理
动态代理 ①动态代理概念理解 动态代理是一种方便运行时动态构建代理.动态处理代理方法调用的机制,很多场景都利用类似机制做到的,比如用来包装RPC调用.面向切面的变成(AOP) 实现动态代理的方式很多, ...
- Python: 字符串格式化format()函数的使用
python从2.6开始支持format,新的更加容易读懂的字符串格式化方法,从原来的% 模式变成新的可读性更强的 花括号声明{}.用于渲染前的参数引用声明, 花括号里可以用数字代表引用参数的序号, ...
- HTTP从入门到入土(2)——HTTP协议发展历史
HTTP协议的发展历史 HTTP/0.9 0.9版本是第一个定稿的HTTP版本,相对较为简陋.它有以下特点: 只有一个命令GET 没有header等描述数据的信息 服务器发送完毕,就关闭TCP连接 注 ...
- OpenCV中Denoising相关函数的简单介绍
参考:http://wenhuix.github.io/research/denoise.html一.基本情况 (一)基本方法 Fast Non-Local Me ...
- 20162326 qilifeng 2018-2019-2 《网络对抗技术》Exp0 Kali安装 Week1
<网络对抗技术>第1次作业 (一)作业任务 1.安装kali 2.设置共享文件夹 (二)操作过程 1.安装kali 因为之前安装过Oracle 的VM VirtualBox 所以直接 进入 ...
- tar: Cowardly refusing to create an empty archive 问题
在解压 .tar.gz文件的时候遇到了这个解压的问题. 原命令:tar -zcvf ···.tar.gz 提示:tar: Cowardly refusing to create an empty ar ...