fastdfs 上传图片出现 java.net.SocketException: Broken pipe (Write failed)

项目场景:

项目场景:使用公司封装的fastdfs工具包上传图片


问题描述

使用公司封装的fastdfs工具包上传文件时,调用的方法并没有对fastdfs client的方法做什么大改动。在并发量不是很大的情况下,有时会报出此错误,频率不高,并且上传图片也成功了。
具体错误信息如下:

2023-02-24 13:17:04.272 [TID:N/A] [pool-4-thread-4] ERROR c.g.t.f.d.conn.DefaultConnection -close connection error
java.net.SocketException: Broken pipe (Write failed)
        at java.net.SocketOutputStream.socketWrite0(Native Method)
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
        at java.net.SocketOutputStream.write(SocketOutputStream.java:143)
        at com.github.tobato.fastdfs.domain.conn.DefaultConnection.close(DefaultConnection.java:73)
        at com.github.tobato.fastdfs.domain.conn.PooledConnectionFactory.destroyObject(PooledConnectionFactory.java:96)
        at com.github.tobato.fastdfs.domain.conn.PooledConnectionFactory.destroyObject(PooledConnectionFactory.java:22)
        at org.apache.commons.pool2.KeyedPooledObjectFactory.destroyObject(KeyedPooledObjectFactory.java:133)
        at org.apache.commons.pool2.impl.GenericKeyedObjectPool.destroy(GenericKeyedObjectPool.java:1128)
        at org.apache.commons.pool2.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:403)
        at org.apache.commons.pool2.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:271)
        at com.github.tobato.fastdfs.domain.conn.FdfsConnectionManager.getConnection(FdfsConnectionManager.java:148)
        at com.github.tobato.fastdfs.domain.conn.TrackerConnectionManager.executeFdfsTrackerCmd(TrackerConnectionManager.java:72)
        at com.github.tobato.fastdfs.service.DefaultTrackerClient.getStoreStorage(DefaultTrackerClient.java:32)
        at com.github.tobato.fastdfs.service.DefaultFastFileStorageClient.getStorageNode(DefaultFastFileStorageClient.java:167)
        at com.github.tobato.fastdfs.service.DefaultFastFileStorageClient.uploadFile(DefaultFastFileStorageClient.java:110)
        at com.github.tobato.fastdfs.service.DefaultFastFileStorageClient.uploadFile(DefaultFastFileStorageClient.java:68)
        at com.tianyi.platform.sdk.fastdfs.module.service.impl.FastdfsServiceImpl.uploadFile(FastdfsServiceImpl.java:54)
        at com.tianyi.service.video.process.modules.service.VideoProcessPreviewImageService.processPreviewImage(VideoProcessPreviewImageService.java:70)
        at com.tianyi.service.video.process.modules.receiver.VideoProcessReceiver.lambda$doProcessVideo$2(VideoProcessReceiver.java:156)
        at java.util.concurrent.CompletableFuture.uniAccept(CompletableFuture.java:670)
        at java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:646)
        at java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:456)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:758)


原因分析:

造成这个问题的原因是:在使用上传至fastdfs中使用了common-pool2的对象池,会有驱逐线程定时销毁之前缓存的连接,而这个连接有可能已经断开,所以关闭的时候会报这个错。但是代码中捕获了这个错误,并且在finally代码块中强制关闭了连接,


解决方案:

我尝试在代码中进行拦截
是这个异常的我就打印一条日志,甚至不打印日志

		// 上传预览图到fastdfs
        try {
            // 返回值示例:group1/M04/F9/FD/wKhvFWOQPy2AXqBxAAAhXwgB5is954.jpg
            spritePath = fastdfsService.uploadFile(imagePath);
        } catch (FileNotFoundException e) {
            log.error("文件未找到,上传预览图失败:" + spritePath + e);
            return false;
        //5.使用Exception 没有捕获到,于是我我想是不是报出的是个错误而不是异常,于是使用了Throwable ,结果还是没有捕获到
        } catch (Throwable t) {
        //} catch (Exception e) {
        //1.首先我想直接捕获此异常但是idea提示不会产生此异常,建议删除,所以我又尝试使用Exception捕获后进行比较,不是的抛出,是的就处理掉不打印信息
        //} catch (SocketException e) {
        	String exception = e.toString();
        	//4.我在此处加了一个日志输出,发现错误还是报出了,但是此条日志并没有打印是没有捕获到?
            log.info("exception= " + exception);
            //2.使用instanceof idea就提示错误,这里没有搞懂 为啥不让这么比较
            //if (e instanceof SocketException) {
            //3.我又尝试这样处理,比较抛出的异常是否为此异常,发现也失败了
            if (exception .contains("SocketException")) {
                log.error("fastDFS断开连接错误,不影响正常业务,无需在意");
            } else {
                throw e;
            }
        }

在日志配置文件中关闭日志打印

因为只是pool清除被断开的connection,记录的日志而已,FastDFS server端默认断开处于IDLE状态60s的connection;不影响正常业务,所以这个问题无需考虑。
所以我参考:https://github.com/tobato/fastdfs_client/issues/230,在log配置文件中加入如下配置,让此错误日志不在打印

<!--不显示ERROR c.g.tobato.fastdfs.domain.conn.DefaultConnection - close connection error 错误日志,
参照:https://github.com/tobato/fastdfs_client/issues/230-->
    <logger name="com.github.tobato.fastdfs.domain.conn" level="OFF" additive="false"></logger>
org.csource.common.MyException: getStoreStorage fail, errno code: 2 at org.csource.fastdfs.StorageClient.newReadableStorageConnection(StorageClient.java:1767) at org.csource.fastdfs.StorageClient.download_file(StorageClient.java:1219) at org.csource.fastdfs.StorageClient.download_file(StorageClient.java:1206) at com.wzdigit.framework.utils.FastDFSUtil.downFile(FastDFSUtil.java:209) at com.wzdigit.srm.dsr.utils.FileUtil.getSingleFile(FileUtil.java:51) at com.wzdigit.srm.dsr.service.bidding.BiddingorderService.getVendorQuotation(BiddingorderService.java:796) at com.wzdigit.srm.dsr.service.bidding.BiddingorderService.sendEmail(BiddingorderService.java:746) at com.wzdigit.srm.dsr.service.bidding.BiddingorderService$$FastClassBySpringCGLIB$$ebfcbd5a.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) at com.alibaba.druid.support.spring.stat.DruidStatInterceptor.invoke(DruidStatInterceptor.java:73) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691) at com.wzdigit.srm.dsr.service.bidding.BiddingorderService$$EnhancerBySpringCGLIB$$80ace30.sendEmail(<generated>) at com.wzdigit.srm.dsr.service.bidding.BiddingorderService$$FastClassBySpringCGLIB$$ebfcbd5a.invoke(<generated>) at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
06-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值