我认为workerman没必要 ,做一个断线重连即可。因为不是多线程,或协程,所以一个进程中从请求来临到请求结束都用一个数据库连接,下一个请求来临只要这个链接还有效还可以接续用,线程不会随着请求的结束而结束,连接池创建多个数据库连接只能是浪费。
php-fmp 更没有必要在程序中做连接池,因为不但一个请求是从上到下都不会有其他请求干扰(协程),也没有多线程问题。请求结束会销毁掉所有资源,但是做一个外部的连接池(非程序中)比如SMProxy有必要,外部程序做连接池,取来即用,不和进程资源一起销毁。
而swoole协程和java的线程有必要数据库连接池,因为协程不是从上到下执行,有可能多个请求同时在被一个进程在处理,有可能并行对数据库的操作,如果还是用一个连接会出现问题,协程或者线程需要自己的连接资源。无论协程和线程都有可能随时销毁,不是和进程的生命周期一样同生共死,创建连接池能避免重复生成连接带来的消耗。
连接池大致上分为2种:
一种是进程内部共享的连接池,也就是一个进程打开多个mysql连接,供多个线程或者协程使用。它的目的是提高单个进程并发能力。但是缺点也很明显,每个进程都维持着多个mysql连接,多进程多服务器则会打开非常多的mysql连接,导致mysql连接数很大,影响mysql服务器性能。因为mysql连接数有限,每增加一台服务器就增加很多mysql连接,所以不可能无限扩展应用服务器,从而限制整个系统并发量。所以这种方案适用于多个请求在一个进程并发处理并且不需要大规模应用集群的时候。workerman虽然支持异步,但是如果使用pdo操作数据库,整个请求退化为同步阻塞,所以使用pdo的时候不需要进程内部连接池。但是如果使用异步mysql组件,并且没有其它同步阻塞业务,则也可以使用进程内部共享连接池。
一种是外部连接池,就是外部一个全局的连接池服务(一般在一台/一组独立的服务器部署),多个进程(或者多服务器)共享。所有调用mysql的地方变成调用这个外部连接池服务,连接池服务代理请求mysql。这种连接池因为可以全局控制mysql连接数,扩展应用服务器数量更加容易。由于是所有服务器所有进程的请求都复用这些连接,所以这些连接的利用率很高。不像进程内连接池,大部分时间大部分连接都是空闲,造成浪费。外部连接池这种方案适用于大规模应用服务器集群,适用于各种应用服务,包括workerman swoole。
所以workerman里大部分情况不需要使用mysql连接池,数据库单例即可。但是如果workerman服务器集群并且数量达到一定规模(几十台上百台),建议使用外部连接池服务,以减少mysql连接数,提高mysql性能。
感谢回复
进程处理任务,根据任务类型的不同,可能mysql连接不同,这种是否是需要全局的连接池服务(如果需要,是怎么实现的呢)?
场景:应用是多租户,每个租户是单独的数据库(可能在一台机器上,可能不是),但所有任务都是放在一队列,根据租户ID区分
不需要连接池
外部连接池,当前进程要连接外部连接池服务,创建这种连接开销比直连数据库创建数据库连接开销小很多吗?