文档章节

PHP-FPM模式下可怕的 MongoDB-PHP-Driver 连接池无节制连接问题

旁观者-郑昀
 旁观者-郑昀
发布于 2013/02/08 22:48
字数 799
阅读 447
收藏 1
@郑昀汇总 创建日期:2013/1
 
问题发生环境:
  • Nginx
  • PHP 5.3.10 as php-fpm extension to nginx
  • mongodb-php-driver 1.2.12
  • MongoDB 2.2
此问题是 MongoDB PHP Driver 1.2.x 的官方特性导致的,描述请看  PHP-202 和   PHP-347 。简单地说,PHP-FPM模式下,每一个 PHP Worker 进程都有自己独立的 mongodb 连接池,从而导致连接数极易超标,内存数也随之倍增。
 
一,PHP服务背景:
某个 Web 应用是通过   Nginx+factcgi  运行的 PHP 程序提供服务的。
PHP-FPM的最大子进程数,是通过 php-fpm.conf 的  max_children  参数设置的(或pm=dynamic时由 spare_servers+start_servers 参数综合决定)。这个值曾被设置为 512
 
二,MongoDB服务背景:
mongodb 实例的最大连接数限制可以通过启动参数中的   maxConns  设置:
  • maxConns:默认值取决于系统的限制(如 ulimit 和 file descriptor)。如果没设置这个参数, mongodb 自己不会限制连接数。但,你不能设置超过 20,000 。
一般不刻意设置 maxConns 参数。
 
三,MongoDB PHP Driver 的可怕连接池特性(BUG?)
MongoDB 官方提供的   mongodb-php-driver  在 1.3.0 以下版本(1.2.0~1.2.1x),拥有一个可怕的连接池实现方案,在执行任何查询时,都会从连接池中请求一个连接,完成之后再归还给连接池。这里的完成是指持有该连接的变量离开了它的作用域。
 
PHP-FPM模式下,一个 PHP Web 应用能对 MongoDB instance 建立的并发连接数计算方式如下:
  • 进程数:max-children = 512 ,那么是 512 个进程
  • 一个MongoDB实例对应一个连接池:主站配置了165和166两个副本集实例;
  • 连接池中的连接数:mongodb-php-driver 对此不做任何限制,可以无限增加直到句柄耗尽为止。
—————— 郑昀:此计算方式出自  mongo.connecting.pools ——————
根据 mongodb 官方文档说明, 虽然连接数无限增长理论上是有可能的,但实际观测发现,一个 Web Server 与一个 mongodb 实例的连接数通常会稳定在一个值上,不会有太大的起伏
那么,假设 一个 PHP Web 应用向 mongodb-165 发起的连接数为
750 个,
该 MongoDB 实例为此需要维护的内存数至少为:
750 × 默认10MB =   7.5 GB
 
五,解决办法
迅速升级到 mongodb-php driver 1.3.2。
 
参考文档:
1)2012-12-9,Connection Handling with the MongoDB PHP driver,英文稿中文翻译稿
2)李丹的测试结果:
“再测试一下驱动升级到1.3.2稳定版后的ab结果,发现close效果很明显,很快的连接数就下降到测试之前的数量了。虽然在峰值上大于老的驱动,但是应该可以解决现有线上的高连接持续的问题。”
4)mongodb-java-driver 定义了一个应用与 mongodb 实例能建立的最大连接数,即 (connectionsPerHost × threadsAllowedToBlockForConnectionMultiplier)个连接:
  • mongo.options.connectionsPerHost:每个Application与 MongoDB 实例能建立的最大物理连接数,默认是10;
  • mongo.options.threadsAllowedToBlockForConnectionMultiplier:可以等待池中有连接可用的最大线程数,默认是5。
5)crazyshell,2012,MongoDB maxConns参数
赠图几枚:
http://ww4.sinaimg.cn/large/61b889f5jw1e0noudfng5j.jpg

© 著作权归作者所有

旁观者-郑昀
粉丝 100
博文 77
码字总数 162700
作品 0
朝阳
私信 提问
十个 MongoDB 使用要点

从 mongodb 阶段性技术总结 中抽取并整理了对大家有帮助的十个要点: 1.mongodb 表名和字段名统一用小写字母 mongodb 是默认区分大小写的,为了避免以前在 mysql 下遇到的大小写敏感导致程序...

旁观者-郑昀
2013/02/08
443
0
抓狂 - php class mongodb driver manager not found

有个与第三方对接的系统,今天对方突然反映无法连接我们的MongoDB数据库,提示php class mongodb driver manager not found错误。对接系统之前一直运行很好,没有出现过这个问题。 服务器挂掉...

杨梅泡酒
2018/11/15
0
0
82.mongodb语句 两种扩展

21.30 mongodb创建集合、数据管理(删除查找等等) 21.31 php的mongodb.so扩展 (两种扩展的不同) 21.32 php的mongo扩展 扩展内容 mongodb安全设置 http://www.mongoing.com/archives/631 m...

axin-linux
04/01
12
0
mongodb创建集合、数据管理、PHP的mongodb扩展、21.32 PHP的mongo扩展

mongodb创建集合、数据管理 创建集合 说明: 前面创建了test1用户,test1用户对db1库读写,对db2只读. 之所以先创建db1库,表示用户在db1库中创建,就一定要db1库验证身份,即用户的信息跟随数...

Linux_Anna
2017/10/20
33
0
你应该知道的那些超时设置或默认参数

郑昀总结 最后更新于2013年6月19日 存储介质 WebServer 中间件 -待续- 赠图2枚:

旁观者-郑昀
2013/06/19
336
0

没有更多内容

加载失败,请刷新页面

加载更多

XXL-JOB使用命令行的方式启动python时,日志过多导致阻塞的解决方式

一、Runtime.getRuntime().exec()的阻塞问题 这个问题也不能算是XXL-JOB的问题,而是Java的Runtime.getRuntime().exec()造成的,BufferedReader的缓冲区大小有限,当不能及时从缓冲区中把输出...

codeobj
1分钟前
0
0
java后端获取字符串标签里面的具体值

1、如下:怎么获取value值,使用Jsoup解决 <select id='department' name='department' class='select' tabindex='6' onchange='changeDept()'><option value=''>院系</optio......

木九天
8分钟前
2
0
Xamarin图表开发基础教程(10)OxyPlot框架支持的图表类型

Xamarin图表开发基础教程(10)OxyPlot框架支持的图表类型 OxyPlot组件支持26种图表,这些图表按照功能和样式可以分为4大类,分别为线型图表、条型图表、金融图表和其它图表。 线型图表 OxyP...

大学霸
12分钟前
2
0
移动端input“输入框”常见问题及解决方法

移动端input“输入框”常见问题及解决方法 1. ios中,输入框获得焦点时,页面输入框被遮盖,定位的元素位置错乱: 当页input存在于吸顶或者吸底元素中时,用户点击输入框,输入法弹出后,fie...

tyou
13分钟前
2
0
初探Android线程池

前言 最近在看OkHttp的源码,看的时候发现有关线程池的运用,自己就仔细想了一下,这个块知识好像不是很牢固。没办法,再研究一下有关线程池的相关知识吧。学习就是一个查漏补缺的过程,最终...

二营长的意大利炮手
20分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部