woker定时任务定时取edis取队列数据,然后插入到mongodb中。当redis队列长期没有数据的时候,然后又在队列里新增一条数据,workerman的定时器取出来后却没有插入到Mongodb中,再次在队列中放入一条数据后,workerman的定时器取出队列的数据后又能插入到mongodb中。例如:今天早晨我队列中没有数据,当提交一条数据到队列中后,定时器一执行便将队列中数据取出,但是这一次并没有插入到Mongodb中,不过接下来再次提交数据到队列中后,就不会出现这个问题了。等过很长时间,大约八九个小时甚至半天的时间,又会出现那个问题。定时器设置的是每秒执行一次。
我遇到过mysql出现过类似的问题,后来发现是mysql连接长时间没通讯就会被mysql服务端关闭,然后报mysql gone away 错误。
感觉你的mongodb也是一样,连接很长时间没通讯被mongodb服务端关闭了,然后再用这个连接插入数据到mongodb就会失败,然后再次插入时mongodb检测到之前关闭了,又重新连接,结果后面的数据插入成功。
其实如果长时间不通讯,我觉得没必要用mongodb mysql长连接,用的时候连,用完就关闭这样最不容易报错。因为本来通讯次数就少,mongodb mysql长连接没必要。
没有用长链接,就是用的时候连。后来在插mongodb操作之前执行了一下查mongodb的操作,这也相当于连了一次Mongodb,但还是出现那种问题
@wo642436249: new MongoClient() 并不是重新连接,在同一个进程中它用的是同一个持久连接。
既然插入失败,你有没有检查返回值?有没有重试?
队列中长期没数据的情况下,当你添加一条数据的时候,队列中的数据被取出,但是并未被成功插到mongodb中,紧接着第二次、第三次......添加数据的时候就能成功将该数据插到mongodb中。还有这个workerman的定时器执行着三个业务,首先执行的就是从redis队列中取数据,然后就是将取出来的数据插入到mongodb,再然后就是往Mongodb中的日志表插入一条日志,很好奇,不论从队列中取出的数据是否成功插入到mongodb(第二步),但是这三个业务逻辑中取队列数据的操作(第一步)和往Mongodb日志表中插数据的操作(第三步)总是会执行成功。
【第一步】是读 redis 这个不说了,与问题无关;【第二步】跟【第三步】是连续两次写 MongoDB,为什么会【第二步】失败而【第三步】成功,一楼已经解释了。
我看了 PHP 文档,1.3 版本以后的 mongodb driver 用的都是持久连接,那么你说的“不是基于长连接的”是怎么做到的呢?
你所说的“第二步之前做了一次查询操作”,查询成功了吗?难道是“查询成功然后紧跟的写操作失败了”这样?无论如何,第二步的写操作你有检查返回值吗?结果如何?
首先是要检测到错误,然后是确认错误原因,然后才谈得上应对处理。
如果是连接闲置超时断开,可以连上之后重试一次。