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 部署在同一机器上,充当连接池。