问题背景
一个web应用的定时任务,每天把mysql的数据全量数据刷新到mongo中(第一步把mongo数据全清除,第二步再分批把mysql数据保存到mongo),一直运行良好。直到有天往这个系统迁移了大概60几w的数据后,发现定时任务把mongo数据删除,但没把mysql数据刷新进去。查看日志,报了如下异常:
Closed connection [connectionId{localValue:5, serverValue:3056655}] to 10.142.232.165:3717 because there was a socket exception raised by this connection.
问题分析
通过跟踪代码,发现是在调用该句代码
mongoTemplate.remove(new Query(), collectionName)
时,报的异常。这是因为数据量大了,这句代码需要花费大量时间,已经超过了配置的时间。配置如下
#一个线程等待链接可用的最大等待毫秒数,0表示不等待,负数表示等待时间不确定,推荐配置120000
maxWaitTime=120000
#链接超时的毫秒数,0表示不超时,此参数只用在新建一个新链接时,推荐配置10,000.
connectTimeout=10000
#此参数表示socket I/O读写超时时间,推荐为不超时,即 0 Socket.setSoTimeout(int)
socketTimeout=60000
解决方案
方案一、将socketTimeout=0,不超时。 --此方案不是很推荐,目前mongo对事务的支持还不是很好,一上来就把数据全删,接着再去查数据往mongo灌。是很危险的操作。
方案二、将全量刷新改成增量刷新,比如只刷新前一天有变化的数据。如果这个数据很重要,更新完后,最好使用邮件发送刷新结果通知。