有用户反映线上查看文件时,文件名与文件内容中的不是同一个,内容也不对,测试环境试了很多次,代码检查了很多次都没有发现问题,于是又去分析日志,
发现一个奇怪的现象,fastdfs每次报错Read timed out后的上个时间段上传的文件会发生错乱的情况,于是就在测试环境模拟让fastdfs发生超时,
通过减小soTimeout和connectTimeout的值,发现当报错超时之后,真的发生了这种情况,上网搜索这种现象也没有答案,于是去查看com.github.tobato的源码,
发现ConnectionManager中
protected <T> T execute(InetSocketAddress address, Connection conn, FdfsCommand<T> command){
try {
// 执行交易
LOGGER.debug("对地址{}发出交易请求{}", address, command.getClass().getSimpleName());
return command.execute(conn);
} catch (FdfsException e) {
throw e;
} catch (Exception e) {
LOGGER.error("execute fdfs command error", e);
throw new RuntimeException("execute fdfs command error", e);
} finally {
try {
if (null != conn) {
pool.returnObject(address, conn);
}
} catch (Exception e) {
LOGGER.error("return pooled connection error", e);
}
}
}
如果发生了异常,就把链接还放回连接池,这样其他操作就有可能继续拿到这个链接来做事。
后来去gitHub查看com.github.tobato的Issues,发现同样有人遇到了这种情况,上面给出了2种解决方案,一种是将连接池设置为1,测试了一下可行,
但是上传效率会受影响。第二个就是作者说更新到最新的1.27.2版本,测试也是可以的,通过下载最新的1.27.2版本的源码,发现对此处做了改进,
如果抛异常之后不再将链接返回给连接池,而是移除掉。