记一次线上Can’t create/write to file ‘/tmp/MYJH1Lmb’ (Errcode: 28 - No space left on device) 错误
## 问题出现 最开始是客户反映后台商品列表查询太慢,当我们自己调查询接口时报错:
Error querying database. Cause: java.sql.SQLException: Can't create/write to file '/tmp/MYJH1Lmb' (Errcode: 28 - No space left on device)\n### The error may exist in class path resource [mapper/SpGoodsSpuMapper.xml]\n### The error may involve
问题的解决
偶然间发现服务使用的rabbitmq中有一条unack消息,这个项目使用了rabbitmq但没有设置acknowledge-mode,也没有做消息的ack处理,默认是自动,如果处理消息时出错会将消息又放回到队列的头部,然后又消费,导致死循环。上面的问题很有可能是这个导致的。
项目的部署使用的是docker容器,要查看日志首先想到进入容器内docker exec -it xx bash
,报错了(忘记记录啥错了…),于是又想到另外一条命令docker logs -f --tail=1000 xxx
这回成功看到了日志,发现错误原因是一条sql查询应该只有一个结果但是返回了两条,去数据库中果然找到了两条编号一样的数据(编号生成规则:四位公司英文+yyyyMMddHHmmss+五位随机数),接下来手动吧编号改掉,去docker容器的看,14G的日志信息~~
应对措施
问题的根本原因是因为生成了相同的编号,然后mq没有做ack处理,然后docker日志大小没做限制。
- 在批量生成code时用set集合存储已存在的code,如果重复则重新生成;
- acknowledge-mode设置为none;
- docker日志限制大小,在docker run时添加参数
--log-opt max-size=10m --log-opt max-file=3
后记
这次的错误的出现是必然的,因为在项目中发现需要使用mq时才临时加入使用,虽然在使用的时候有考虑到ack,包括这些问题的出现都有预料,但是在对如果出现错误时消息的处理方式没有方向而搁浅。