pdo长连接到底如何使用?

他们说

他们说,pdo连接持久化后持有相同凭证的请求可以使用原来的连接,

从而避免反复创建和关闭连接带来的耗时,

而且,操作上非常方便,

只要在创建pdo对象的时候,

指定PDO::ATTR_PERSISTENT => true就可以了,

这么好,

我也要试下

并没有

首先,我们先看下已有的数据库连接,

这是我本地的navicate产生的连接,后面对比的时候,需要排除这两个连接,

接着,使用持久连接的方式创建一个pdo对象,并执行下查询操作,

通过cli模式来运行脚本,

连接成功,看下连接还在不在,

结果并没有新增连接,也就是说,连接并没有被持久化,

嗯。。。。。。。。。。

貌似我们的打开方式有点问题,

仔细一想,连接要想持久化,必须寄生在一个常驻进程中,

而php脚本运行到结束后,php进程就结束了,

所以持久化肯定不是在php进程中进行的,

那难道是pdo自己产生了常驻的进程来维持连接?

通过对比运行前后的进程,

也并没有发现新的进程产生。。。。。。

需要常驻的进程

无意间了看到了有人在fpm模式下使用pdo长连接的文章,

突然明白了,

fpm不就是常驻的进程吗,

pdo连接在fpm中产生,并随着当前fpm进程的结束而销毁

不求同年同月同日生,但求同年同月同日死,

说的就是他们的关系。

再次实验,还是一样,先观察已有的连接,

和上图一样,就不放图了,

接着,为了使用fpm方式运行php脚本,

我们将脚本写成接口的形式,从浏览器访问该接口,

nginx收到请求后将请求转发给某个fpm进程,

在fpm进程中运行php脚本,

脚本运行结束后,php进程退出,

但是fpm进程不会退出,

也因此,pdo对象得以保留

 

 

 出现了新的连接!连接终于被保留下来了!

 一个fpm进程一个连接

刷新浏览器,再次请求接口时,

又多了一个新的数据库连接!

再刷新一次,又多了一个连接!

不是说持久化连接可以被复用的吗?

现在连接是持久化了,但是并没有被复用啊!

这么搞,由于连接一直没有被销毁,mysql连接很快就会被耗尽!

再仔细想想,

连接对象是保留在fpm进程中的,

理论上,如过该fpm进程已经有了持久化的pdo对象,应该不会再去创建新的pdo对象了,

难道是,其他的fpm进程创建的?

当前有3个fpm进程与mysql建立了连接,

再一次通过浏览器发出请求,

果然,出现了新的fpm进程,并创建了新的连接!

连接复用了吗?

我们修改fpm的配置文件,将子进程数设为静态,并且最大值为1,防止fpm-master动态创建子进程,

看下当前的mysql连接情况,发现只有mysql一个人孤独的监听在3306端口上(navicate因为长时间没有操作,连接断开了)

 

通过浏览器发起一次请求,

可以看到有连接产生,

再次发起请求,

还是同样的连接,

由于fpm子进程数只有1个,且不会动态增加,因此也不会产生新的连接,

连接终于被复用了!

总结

1.连接需要寄生在进程中, 要想维持长连接必须要有常驻的进程作为承载 

2.在fpm模式下使用pdo长连接,一定要控制fpm进程数量小于mysql最大连接数,否则mysql连接数会被耗尽!

posted @ 2020-08-22 15:01  jiage666  阅读(1505)  评论(0编辑  收藏  举报