PHP扩展模块memcached长连接使用方法分析


Posted in PHP onDecember 24, 2014

      网上广泛流传着一篇文章,讲述php的两个扩展模块memcache和memcached的区别,其中特意强调了memcached与memcached一个很大的区别是memcached模块不支持长连接。以至于后来很多年我都认为memcached是不支持长连接的,其实不然,memcached扩展模块从很早的版本开始就已经支持长连接了。从扩展模块的源码注视中我们就能看到:

/* {{{ Memcached::__construct([string persistent_id[, callback on_new[, string connection_str]]]))

   Creates a Memcached object, optionally using persistent memcache connection */

static PHP_METHOD(Memcached, __construct)

{

从php的手册身上我们可以看到memcached的扩展模块提供的构造函数提供一个参数persistent_id可选项,手册中这样介绍:

      默认情况下,Memcached实例在请求结束后会被销毁。但可以在创建时通过persistent_id为每个实例指定唯一的ID, 在请求间共享实例。所有通过相同的persistent_id值创建的实例共享同一个连接。 

这个参数的含义就是说如果你传递了一个命名id给到构造方法,那么就会建立长连接,通常我们使用的都是PHP-FPM模式,这样PHP-FPM进程就会和memcached服务简历一条长连接通道。我们也可以理解为persistent_id就是一个连接池名字,所有php-fpm进程都是这个连接池中的一员。

     但我们需要注意的是php是解释性语言,当php第一次通过memached模块建立起长连接后,切记后续的php执行就不要再通过memcached的构造函数构建相同persistent_id命名的长连接,可以建立不同persistent_id名字的长连接,如果是相同的名字被php重复执行,一定会导致php-fpm的进程异常导致与memcached的通信越来越慢,同时根据libmemcached的版本不同还会导致php产生coredump。

    那么我们如何避免单个php-fpm在建立完以persistent_id命名的长连接后不再重复建立长连接呢?其实在PHP带有评注的手册上是有讲解的,内容如下:

When using persistent connections, it is important to not re-add servers.

This is what you do not want to do:

$mc = new Memcached('mc');
$mc->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
$mc->addServers(array(
  array('mc1.example.com',11211),
  array('mc2.example.com',11211),
));

Every time the page is loaded those servers will be appended to the list resulting in many simultaneous open connections to the same server. The addServer/addServers functions to not check for existing references to the specified servers.

A better approach is something like:

$mc = new Memcached('mc');
$mc->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
if (!count($mc->getServerList())) {
  $mc->addServers(array(
    array('mc1.example.com',11211),
    array('mc2.example.com',11211),
  ));
}

通过使用getServerList()方法来检查当前执行使用的php-fpm进程容器中是否已经存在相同名字的长连接资源,如果存在就不要重复使用addServers() 方法来新增长连接配置。

PHP 相关文章推荐
smarty+adodb+部分自定义类的php开发模式
Dec 31 PHP
PHP为表单获取的URL 地址预设 http 字符串函数代码
May 26 PHP
解析file_get_contents模仿浏览器头(user_agent)获取数据
Jun 27 PHP
php向js函数传参的几种方法
Aug 10 PHP
PHP中new static() 和 new self() 的区别介绍
Jan 09 PHP
php rsa加密解密使用详解
Jan 14 PHP
PHP安装threads多线程扩展基础教程
Nov 17 PHP
删除PHP数组中头部、尾部、任意元素的实现代码
Apr 10 PHP
PHP实现权限管理功能示例
Sep 22 PHP
彻底搞懂PHP 变量结构体
Oct 11 PHP
PHP设计模式之模板方法模式定义与用法详解
Apr 02 PHP
php文件后缀不强制为.php的实操方法
Sep 18 PHP
Yii框架在页面输出执行sql语句以方便调试的实现方法
Dec 24 #PHP
php使用pdo连接并查询sql数据库的方法
Dec 24 #PHP
php将access数据库转换到mysql数据库的方法
Dec 24 #PHP
php启用sphinx全文搜索的实现方法
Dec 24 #PHP
php中mail函数发送邮件失败的解决方法
Dec 24 #PHP
微信公众平台接口开发入门示例
Dec 24 #PHP
PHP获取youku视频真实flv文件地址的方法
Dec 23 #PHP
You might like
php代码运行时间查看类代码分享
2011/08/06 PHP
使用PHP实现密保卡功能实现代码<打包下载直接运行>
2011/10/09 PHP
网页前端优化之滚动延时加载图片示例
2013/07/13 Javascript
javascript 处理null及null值示例
2014/06/09 Javascript
60个很实用的jQuery代码开发技巧收集
2014/12/15 Javascript
简介AngularJS的HTML DOM支持情况
2015/06/17 Javascript
分享12个实用的jQuery代码片段
2016/03/09 Javascript
js Canvas实现圆形时钟教程
2016/09/19 Javascript
jQuery实现的浮动层div浏览器居中显示效果
2017/02/03 Javascript
HTML5实现微信拍摄上传照片功能
2017/04/21 Javascript
JavaScript 中的12种循环遍历方法【总结】
2018/05/31 Javascript
layer.close()关闭进度条和Iframe窗的方法
2018/08/17 Javascript
原生JS实现的自动轮播图功能详解
2018/12/28 Javascript
理解JavaScript中的对象
2020/08/25 Javascript
pyqt4教程之messagebox使用示例分享
2014/03/07 Python
编写Python的web框架中的Model的教程
2015/04/29 Python
Python实现信用卡系统(支持购物、转账、存取钱)
2016/06/24 Python
Python2和Python3中print的用法示例总结
2017/10/25 Python
使用python对文件中的数值进行累加的实例
2018/11/28 Python
对Python中实现两个数的值交换的集中方法详解
2019/01/11 Python
对PyQt5的输入对话框使用(QInputDialog)详解
2019/06/25 Python
python 批量解压压缩文件的实例代码
2019/06/27 Python
python3.6+django2.0+mysql搭建网站过程详解
2019/07/24 Python
Python Pandas 如何shuffle(打乱)数据
2019/07/30 Python
Python requests获取网页常用方法解析
2020/02/20 Python
django admin后管定制-显示字段的实例
2020/03/11 Python
联想韩国官网:Lenovo Korea
2018/05/10 全球购物
军训的自我鉴定
2013/12/10 职场文书
运动会广播稿200米
2014/01/27 职场文书
高中军训感想800字
2014/02/23 职场文书
促销活动方案模板
2014/02/24 职场文书
环保宣传标语
2014/06/12 职场文书
十佳好少年事迹材料
2014/08/21 职场文书
“四风”问题的主要表现和危害思想汇报
2014/09/19 职场文书
工作经验交流材料
2014/12/30 职场文书
MySQL8.0的WITH查询详情
2021/08/30 MySQL