workerman与数据库结合的时候,产生的问题和解决案例。

jorry

workerman与数据库结合的时候,产生的问题和解决案例。

10320 5 0
5个回答

walkor

这里拿mysql数据库为例
可能产生的问题如下:

一般数据库类都是单例模式,也就是一个数据库实例对应一个数据库链接,后续直接复用了这个数据库链接,避免了建立链接TCP三次握手、权限验证、链接关闭TCP四次握手等网络交互过程。在worekrman中这种复用更为彻底,每个进程只需要创建一个数据库实例,在整个进程生命周期内(可能很长很长)都可以一直复用这个链接,所以在workerman中使用数据库等资源(包括其它存储如memcache、redis等等)是非常高效的。

但是在mysql中会有一个问题,就是mysql服务端会定时关闭一些长期没有活动的数据库链接,当链接关闭时,在php的mysql扩展层面并没有重连机制,导致在php中使用这个链接已经被服务端断开的数据库实例时会报 mysql gone away 错误,导致数据库操作失败。从这里看出来其实这并不是workerman的问题。应该算作php mysql扩展机制或者说mysql机制的问题

这个问题是很好解决的,比如
1、在性能要求不苛刻的时候,不使用单例模式,每次重新创建链接
2、使用单例模式,出错时判断错误码 是不是2006(mysql gone away固定是这个错误码),是的话重连(或者说重新创建一个数据库实例)
3、单例模式,每次请求完毕后删除实例
4、定时任务(Man\Core\Lib\Task),定时ping mysql,不让mysql关闭链接

经过测试 memcache和redis会自动重连,没有这个问题

  • 暂无评论
aguai

我一直担心redis的订阅,长时间没有消息,连接会不会中断,导致订阅出问题。walkor的意思是不会有这个问题?

  • 暂无评论
walkor

这个和redis服务端配置、网络环境、redis客户端都有关系,需要实际环境测试才能知道

  • 暂无评论
osacar

@walkor 我的业务对数据库性能要求不高,那我用sqlite数据库会不会也存在上述mysql数据库的问题?

  • 暂无评论
walkor

业务对性能要求不苛刻可以用短链接就不会有问题

  • 暂无评论
年代过于久远,无法发表回答
🔝