源码分析并解决生产环境关于关闭其中一台Fastdfs集群服务器造成异常

源码:https://gitee.com/Leelinkai/demo2.git

生产事故还原:

生产中,fastdfs是以集群模式部署,但是由于运维同事需要对服务器升级,因此关闭fastdfs集群的其中一台,本以为是集群模式,按理对生产不构成影响,但实际是,运维停机其中一台fastdfs后,线上交易记录下载,商户入网图片上传等涉及到fastdfs的应用都呈现偶发性异常报错,因此运维同事赶紧重新启动fastdfs,异常消除。

报错信息:Connection reset

                 connection reset by peer, socket write error

事故分析:

出现上述异常,需要有个人去搞懂异常的原因,并给出解决方案,使服务器能继续升级并不影响生产,因此我也接受了这个任务。

首先,遇到此类问题,又涉及第三方插件集群,比较重要的一环就是还原事故现场。但是实际中,我们不能拿生产环境做测试,碰巧我们开发环境和测试环境又是单机模式。所以,我需要去调研生产环境的搭建情况并模拟一样的情况去搭建部署。下图是我调研生产环境fastdfs(v4.06)集群的搭建情况:

至于Fastdfs集群的搭建方法以及组别等相关概念,还需要大家自行去学习和搭建,这里就不做进一步讲解了。

①现场还原

首先大家看下通过此命令查看集群状态(注意:根据实际的搭建环境看脚本的位置):

/usr/local/bin/fdfs_monitor /etc/fdfs/storage.conf 

然后重点来了,直接关闭其中一台虚拟机,假设我关闭了 192.168.78.24 ,然后我去了192.168.78.25,去执行集群查看命令:/usr/local/bin/fdfs_monitor /etc/fdfs/storage.conf  ,竟然发现 192.168.78.24 依旧是激活情况,如图所示:

 然后等了好一会儿,再去执行查看集群命令,发现192.168.78.24是 OFFLINE 状态。 

上述现象会反映一个什么问题,大家想想:如果停机那瞬间,192.168.78.24 又是激活状态,意味着如果有服务去加载 192.168.78.24 ,那么这时操作文件就会有问题了。

接来下,我重启 192.168.78.24 ,让集群恢复正常。然后改下上传的代码,先上传一次,然后睡5秒时候突然强制停机一台Fastdfs(即192.168.78.24),再上传一次就会报错异常。

 看到异常现象的时候,先给大家看下fastdfs客户端的加载流程,首先Fastdfs客户端的方法是静态的,同时客户端的资源都是静态的,如图所示:

为啥是静态,因为加载fastdfs客户端资源的时候,如果采用每次实例化的话,以为了每次调用fastdfs服务都会去初始化fastdfs资源,并且需要建立socket,倘若对并发处理的话,这对于服务器是很致命的。

如上面代码所示,获取到StorageServer后,在加载静态资源StorageClient1的时候,StorageServer是保存在StorageClient1这个类中。接下来,我们进一步跟进上传的核心代码块 StorageClient.do_upload_file()方法,如图所示:

这里我就不debug了,直接打印日志给大伙看。大家看到, 睡5秒后,再次上传文件,再次通过StorageServer去获取socket信息是没有问题,因为storageServer 是继承 TrackerServer ,由于第一次加载了sock,所以sock不为null,这次直接返回了。

 在代码层面实际报错是这里,至于怎么定位到这里,我就不一一细说展示了。

大家在这里会看到 Connection reset 异常报错了,和上面的截图最初报错是一致的。相必到这里大家已经知道原因了,停机一台fastdfs集群,最终会造成IO流读取的时候,在调取isConnectionReset()就返回true,这个环节就会出现问题,报异常了。

解决办法:

方法一:修改底层源码,以上传方法为例。

修改前:

修改后:

方法二:修改客户端外层。即FastDFSClient。思路是对静态资源的再封装一个成一个方法,在catch里面重新初始化,再去请求一次。如图所示:

不管哪种方式,最后都解决了上传文件停机异常处理。由于核心类都是静态资源,所以catch第一次异常后,后续服务就一直是正常的了。如下图所示:

 

总结:

①对于fastdfs集群,真要停掉其中一台,请优雅停机。即执行fastdfs命令关闭服务。/usr/local/bin/stop /etc/fdfs/storage.conf ,使用此命令,集群当前storage马上置为OFFLINE 状态,避免恰好这是有服务加载造成异常。

②遇到问题,我们更多要想办法还原现场,同时有读源码的习惯,从源码去追溯根源,才能更好地定位和解决问题。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值