[求助] 求定位问题点: ThinkPHP 5 环境, PHP -fpm: pool 不释放数据库连接

2018-08-01 08:51:18 +08:00
 whatever93
是这样,我们用的是 nginx+php-fpm,我最近发现服务器上的 php-fpm 连接数据库的数量随时间而增长,一直是 ESTABLISHED 状态,查了 fpm 的 slowlog 没有信息。框架开发同学说用的 ThinkPHP 5 版本,说由框架来控制数据库释放,求大家给点思路……多谢多谢……
3746 次点击
所在节点    问与答
18 条回复
whatever93
2018-08-01 09:00:42 +08:00
过不了两天就从 20 多编程 100 多……前几天到了 500 个 ESTABLISHED。。。最后只能重启 php-fpm。但这不是最终方法啊……
whatever93
2018-08-01 09:03:08 +08:00
是不是 php 和数据库建立的长连接?
byteli
2018-08-01 09:03:11 +08:00
pconnect 的原因?
tomczhen
2018-08-01 09:06:22 +08:00
数据库这边应该是有闲置释放的时间配置的。
whatever93
2018-08-01 09:15:00 +08:00
数据库是 MongoDB
whatever93
2018-08-01 09:15:10 +08:00
@tomczhen 数据库是 MongoDB
torbrowserbridge
2018-08-01 09:19:06 +08:00
persistent connection
dawniii
2018-08-01 09:21:57 +08:00
我记得 php7 的 mongodb 扩展只支持长连接,没有短连接的配置。很无语。。。
ftpgxm
2018-08-01 09:34:33 +08:00
PHPFPM 模式下 MongoDB 连接不会随着请求结束而关闭,可以考虑建立连接池来处理
whatever93
2018-08-01 09:35:33 +08:00
@dawniii 用的是 php5,刚查询了一下 php7 连接会自动释放 而 php5 不会
jsjscool
2018-08-01 09:35:39 +08:00
php-fpm 的进程管理器改为 static 就行了
whatever93
2018-08-01 09:53:39 +08:00
@byteli 是通过 mongodb 驱动连接的
whatever93
2018-08-01 09:58:54 +08:00
@jsjscool 超过了连接限制 nginx 那边不会 502 么……
onion83
2018-08-01 10:01:35 +08:00
这个不是框架的问题,MongoDB 的驱动 MongoClient 默认建立的就是长连接 persistent connection 且不能直接关闭(而且官方也不推荐你关闭,close 之后可能没啥效果)。

为什么不能关闭是有原因的,因为 mongodb 的架构了单独实例 (Standalone) 之外,还有副本集架构( ReplicaSet ),这意味着每个 php-fpm 都要每个非隐含节点建立通讯关系,为什么要建立通讯关系,这是因为 Mongodb 有复杂的读策略(read Preference)、读关注(Read Concern),这意味着一开始你往数据库写完数据之后,很可能马上去重数据库读,如果这个时候再去建立连接的话,效率就会非常低,还有如果诸如 Tags、session、事务(4.0) 等特性,每次都要找对应的节点,还有做验活、延时选择等操作,你会发现驱动做的东西简直是太重了,活脱脱就是一个数据库中间件要干得活儿。

遗憾的是,php-fpm 这种模式下,每个 worker 的连接( m )都是不共享的,这意味着每个 worker 都会 db 创建一个长连接,如果是副本集架构( n ),每个 web 的机器创建的连接数更为高 m*n,驱动干那么重的活儿,还不如一开始建立好长连接,省得每次都折腾。所以不需要太在意,也不要可以可以去关闭它。

但是,在集群环境下,这个连接数的问题就需要注意了,虽然 mongod 默认支持 100w 连接,但是很可能 linux 系统本身本身没调优过,系统对程序已经做出限制了。例如每个机器开 1024 个 php-fpm,一共 50 台机器,每个 mongod 就要接收 51200 个连接,此时很可能系统已经直接把 mongod 杀了。

在 30 台以下机器,不需要太关注连接数问题,如果更多,就要考虑在 php-fpm 外再做一层连接池了(遗憾的是,目前还没找到很好的解决方案)。终极的解决办法,可能是直接上分片架构( Sharding ),把 mongos 和 php-fpm 部署在同一机器上,充当连接池。
whatever93
2018-08-01 10:12:37 +08:00
@onion83 感谢。。google 了下也没有其它方法了……而没上分片,用的副本集,暂时的解决方法只能是通过 zabbix 监控连接数得到阈值后触发脚本了
另外,给以后遇到的人一个三方驱动的思路吧……
https://bbs.csdn.net/topics/392258373
https://github.com/yuri0229/mongodb-php-driver-dpc
jsjscool
2018-08-01 10:18:52 +08:00
@whatever93 static 下的连接数根据自己的 CPU 和内存评估。比如 400, 理论上最多有 400 个 mongod 长连接。生产环境 php-fpm 的 pm 参数建议使用 static。和 nginx 没有任何关系。
whatever93
2018-08-01 10:26:33 +08:00
@jsjscool 我试试 多谢
lolizeppelin
2018-08-01 13:39:18 +08:00
坑在 f CGI 233

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/475813

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX