fdfs踩坑全记录

当我在使用django框架为后台管理admin页面自定义文件存储时,使用了fastdfs文件存储系统,但测试的时候报了很多错误:

首先第一个:
configparser.NoOptionError:No option ‘connect_timeout’ in section: ‘config
在这里插入图片描述
configparser是python解释器读取配置文件的一个函数,这里的意思是它没有读取到配置文件中的设置项:connect_timeout
打开我们的配置文件client.conf看看,终端输入sudo vi /etc/fdfs/client.conf
没问题呀,配置文件client.conf有connect_timeout这个配置项
在这里插入图片描述
那应该就是项目代码有问题了。
我们先从client配置文件的读取找起,它是在创建FDFFStorage()对象,初始化的时候导入的。
在这里插入图片描述
我们先前后打印看看是什么东西。
在这里插入图片描述
这里打印出来什么都没有,说明get_tracker_conf()没有获取到配置文件的内容,好吧,按住ctrl 同时鼠标左键点击get_tracker_conf,进入到它的源码看看。

然而在这里我踩了个大坑,不过这个坑也可以说是我自己挖的。

这里废话说一下我踩的坑:
我一开始不是ctrl + 鼠标左键去找源码的,而是从venv——Lib——site-packages——fdfs_client下面找到了一个client.py文件。
在这里插入图片描述
我就是这个文件夹下面去找的,因为我们在自定义存储文件的storage.py文件中,调用了get_tracker_conf函数去读取client.conf文件,获取里面的配置详情。所以我自然想到先找这个函数,而我记得是在这个文件夹下面的fdfs_client文件。
就先进去看它读取到的内容是怎么样的。
但是非常奇怪,我在这里前后设置了几个print(),并且直接在模块中调用了这个函数,执行了这个模块,但控制台始终没有输出任何信息。
在这里插入图片描述
后来恍然大悟,这个文件是在虚拟环境venv下的,而我的项目是在dailyfresh虚拟环境下运行的,
在这里插入图片描述
所以它调取的不是这个在venv下面的client.py文件,而是在python3.5下面的dist-packages下面的client.py文件。
在这里插入图片描述
这个坑也是我自己挖的。我这个项目其实已经在windows上面运行过了,那个venv就是在windows上的pycharm创建django项目时,自动建的一个虚拟环境。但是搬到了linux上,我又重建了一个虚拟环境dailyfresh,并在运行在dailyfresh虚拟环境上,但是找文件的时候没有注意到,就找错了文件。

这个坑其实可以避免的,有2点可以避免的:
1、你在storage.py文件里要找到这个get_tracker_conf()函数的源码,只要按住ctrl,同时点击鼠标左键,它就自动跳转到源码位置了。
2、注意虚拟环境不同,如果你是在windows上搬到了linux运行的,并且重建了虚拟环境,那venv文件夹就可以删掉不理它了。
在这里插入图片描述
好吧,专属于我的第一个大坑就过去了。

接下来我们调试一下get_tracker_conf()这个函数看看是什么情况。
我直接在这个模块里面调用get_tracker_conf(),给它传了配置文件的绝对路径,并且在几个关键节点设置了print,右键运行这个模块。
在这里插入图片描述
结果输出如下:
报了另一个错:
TypeError: int() argument must be a string, a bytes-like object or a number, not list
先不要管它,我们先看看print()在控制台输出了什么内容
在这里插入图片描述

看print()的输出说明了:
程序在执行到print(cf.read(conf_path)后,直接跳转到报错了,而且cd.read(conf_path)打印出来的内容竟然还是一个路径列表,而不是配置文件client.conf里面的内容,这是不正常的。既然这样我们再去看看这个Fdfs_ConfigParser()对象,提供的read()方法到底是什么,同样ctrl + 鼠标左键read(),进入read的源码看看。
在这里插入图片描述
结果如下:它是先判断传入的filenames是不是basestring类型,如果是就放进去一个列表,然后再便历这个列表,逐一打开取出每个文件的内容;如果不是就直接遍历这个filenames,逐一打开读取文件内容。
在这里插入图片描述
那么这里就有2个问题了:
1、basestring是什么类型的数据?
查了一下得到:basestring是str和unicode的超类(父类),也是抽象类,因此不能被调用和实例化,但可以被用来判断一个对象是否为str或者unicode的实例,isinstance(obj, basestring)等价于isinstance(obj, (str, unicode));

好吧,那我自己来试试这个isinstance(filenames, basetring)的执行结果是什么,打开cmd,打开ipython。
在这里插入图片描述
结果是,我第一次写错了,但第二次没写错,还是报了个basestring is not defined。
这么奇怪的,我一直学的是python3 ,但从来没有见过basestring这种类型,那么会不会是python 版本的问题呢?

好吧,打开ubuntu试试python2来执行会是什么结果。
在这里插入图片描述
果然是版本的问题,在python2解释器下,得到了true的结果,说明这个basetring的类型是仅存在python 2以前的版本的,在python 3 环境下用它判断,就会报错,再次在ubuntu验证一下,果然没错
在这里插入图片描述
2、我们传入的文件有没有被读取出来?
很明显,我们传入的是一个字符串,而且使用的是python3解释器,在执行if isinstance(filenams, basestring)这一行肯定是不满足的,甚至会报错,即使它不报错,往下继续执行,到了for filename in filenames这一行也会报错,因为我们传入的filenames是str类型的,不是list类型,无法便历,于是在try这里就报错,直接跳到了else,把filename添加到read_ok = []这个空列表中,因此我们最后得到的就是[’/etc/fdfs/client.conf’]。
在这里插入图片描述
那么问题就知道了,我之前安装的fdfs_client-py-master.zip文件,是只适用于python 2的,所以我们要找一下python 3 版本的怎么安装。
在这里插入图片描述
最后找到这个兄弟的写得不错,里面还写到怎么避免一些坑
https://www.cnblogs.com/jrri/p/11570089.html

解决方法:
1、找到你原先安装的fdfs_client两个包,都删掉;可能会提示无法删除,那就进入终端删除。
在这里插入图片描述
我的是在/usr/local/lib/python3.5/dist-packages下面的:
sudo rm -r fdfs_client
sudo rm -r fdfs_client_py-1.2.6.dist-info
在这里插入图片描述
2、重新下载:
不用切换环境,直接在终端出入pip install py3Fdfs
在这里插入图片描述
接下来就能在项目中找到了
在这里插入图片描述
然后开启服务,python manage,py runserver,再次在浏览器测试上传文件。
好的,然后又报错了:
在这里插入图片描述
很开心有没有,我们前面那个问题已经解决了,但也很扎心,又来了一个新问题了。
这个报错是没连接上192.168.1.104,我们的nginx服务器拒绝了,可能是2个原因:
1、nginx服务器没开;
2、fdfs服务器没开;
查一下看看:
ps aux | grep fdfs
ps aux | grep nginx
确实2个都没开。
在这里插入图片描述
那就简单了,直接开启:
sudo service fdfs_trackerd start
sudo service fdfs_storaged start
cd /usr/local/nginx
sudo sbin/nginx
再查一下:
ps aux | grep fdfs
ps aux | grep nginx
出现下面的画面代表已经开启了。
在这里插入图片描述
好了,再次运行项目
python manage.py runserver
再次尝试上传文件:
很幸运,上面的问题又解决了,很不幸,又来一个新问题了。
好吧,这个问题其实就是_save()函数最后返回的文件名,需要解码。
在这里插入图片描述
解决方法:在storage.py文件的_save方法中,把返回的filename改成filename.decode()
在这里插入图片描述
改完了,再试一下上传文件
在这里插入图片描述
终于成功添加了,没有报错。

我只能说,这fdfs的坑真的好多,心累。

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
要使用Java操作FastDFS,你需要引入FastDFS的Java客户端库。可以使用Maven或者直接下载jar包的方式导入库文件。在pom.xml文件中添加以下依赖项: ``` <dependency> <groupId>net.oschina.zcx7878</groupId> <artifactId>fastdfs-client-java</artifactId> <version>1.27.0.0</version> </dependency> ``` 然后,你需要编写一个Java工具类来操作FastDFS。可以参考以下代码: ``` import java.io.IOException; import org.csource.common.MyException; import org.csource.fastdfs.ClientGlobal; import org.csource.fastdfs.FileInfo; import org.csource.fastdfs.StorageClient; import org.csource.fastdfs.StorageServer; import org.csource.fastdfs.TrackerClient; import org.csource.fastdfs.TrackerServer; public class FastDfsUtil { private static TrackerClient trackerClient = null; private static TrackerServer trackerServer = null; private static StorageServer storageServer = null; private static StorageClient storageClient = null; static { try { ClientGlobal.init("fdfs_client.conf"); trackerClient = new TrackerClient(); trackerServer = trackerClient.getConnection(); storageClient = new StorageClient(trackerServer, storageServer); } catch (Exception e) { e.printStackTrace(); System.out.println("FDFS工具初始化失败!"); } } public static FileInfo getFileInfo(String savepath) throws IOException, MyException { String group = ""; // 存储组 String path = ""; // 存储路径 try { int secondIndex = savepath.indexOf("/", 2); // 第二个"/"索引位置 group = savepath.substring(1, secondIndex); // 类似:group1 path = savepath.substring(secondIndex + 1); // 类似:M00/00/00/wKgBaFv9Ad-Abep_AAUtbU7xcws013.png } catch (Exception e) { throw new RuntimeException("传入文件存储路径不正确!格式例如:/group1/M00/00/00/wKgBaFv9Ad-Abep_AAUtbU7xcws013.png"); } FileInfo fileInfo = storageClient.get_file_info(group, path); return fileInfo; } } ``` 在上述代码中,我们使用FastDFS的Java客户端库,初始化一个TrackerClient、TrackerServer和StorageClient实例。然后,可以调用getFileInfo方法来获取文件信息,传入文件的存储路径作为参数。该方法会返回一个FileInfo对象,包含了文件的信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值