fastdfs分布式在docker和python中的运用

Docker安装FastDFS

可以利用已有的FastDFS Docker镜像来运行Fast DFS。
获取镜像可以通过下载:

sudo docker image pull delron/fastdfs

将容器上的文件夹映射到本地路径并启动tracker和storage服务器:

docker run -dit --network=host --name=tracker -v /var/fdfs/tracker:/var/fdfs delron/fastdfs tracker

注意:-v是指定本地目录
storage服务器指定tracker调度服务器的地址和端口(默认22122)和地址映射

docker run -dit --network=host --name storage -e TRACKER_SERVER=192.168.87.128:22122 -v /var/fdfs/storage:/var/fdfs delron/fastdfs storage

然后sudo docker container ls看一下是否运行了容器,这样就成功了

(django-py3) python@ubuntu:~/Desktop$ sudo docker container ls
[sudo] python 的密码: 
CONTAINER ID     IMAGE             COMMAND                 CREATED            STATUS          PORTS          NAMES
73dbe8eedad9     delron/fastdfs    "/usr/bin/start1.sh …"  6 hours ago        Up 6 hours                              storage
b86c8169081f     delron/fastdfs    "/usr/bin/start1.sh …"  6 hours ago        Up 6 hours                              tracker

FastDFS的python客户端

安装python客户端

从GitHub下载:https://github.com/JaceHo/fdfs_client-py
这个地址也是查看使用的地方,然后pip安装下载的包(注意要安装到虚拟环境或者自己环境中):

pip install fdfs_client-py-master.zip
pip install mutagen
pip install requests

开始简单的使用

先定义自己的配置文件

使用FastDFS客户端,需要有配置文件。在项目目录下新建fastdfs目录,创建一个client.conf配置文件:

# 工作文件夹,日志存在此
base_path=/home/python/Desktop/shanghuiyoupin/shanghui/fastdfs/logs
# tracer server列表,多个tracer server的话,分行列出
tracker_server=192.168.52.128:22122

如果需要配置更多地内容,也可以只写上面两个设置:

# 连接超时时间 默认30秒
connect_timeout=30

# 网络超时时间
# default value is 30s
network_timeout=60

# 工作文件夹,日志存在此
base_path=/home/python/Desktop/shanghuiyoupin/shanghui/fastdfs/logs
# tracer server列表,多个tracer server的话,分行列出
tracker_server=192.168.52.128:22122

#日志级别
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=info

# 是否使用连接池
use_connection_pool = false

# 连接闲置超时时间,连接如果闲置的时间超过本配置,则关闭次连接,单位秒
connection_pool_max_idle_time = 3600

# 是否从tracer server读取fastdfs的参数,默认为false
load_fdfs_parameters_from_tracker=false

# 是否使用storage id 替换 ip,默认为false
# 和tracker.conf该参数含义一样
# 本配置只有在load_fdfs_parameters_from_tracker=false时生效
# 本配置默认为false
use_storage_id = false

# 指定storage id的文件名,允许使用绝对路径
# 和tracker.conf该参数含义一样
# 本配置只有在load_fdfs_parameters_from_tracker=false时生效
storage_ids_filename = storage_ids.conf

#HTTP settings
#http.tracker_server_port=8080

#引入HTTP相关配置
##include http.conf

上传文件需要先创建Fdfs_client的对象,并指明配置文件

这是示例,在你需要上传文件的时候使用

from fdfs_client.client import Fdfs_client
client = Fdfs_client('shanghuishop/fastdfs/client.conf')
# 通过创建的客户端对象执行上传文件的方法:
client.upload_by_filename('文件名')
# 或
client.upload_by_buffer(文件bytes数据)

用python调试一下,打印结果其中Remote file_id就是存储路径,对应为/var/fdfs/storage/data/00/00/wKg0gF0TKDiAIwKCAAiHNHphWVQ359.jpg

>>> from fdfs_client.client import Fdfs_client
>>> client = Fdfs_client('/home/python/Desktop/shanghuiyoupin/shanghui/fastdfs/client.conf')
>>> ret = client.upload_by_filename('/home/python/Desktop/图片/timg.jpg')
getting connection
<fdfs_client.connection.Connection object at 0x7fc42065ac88>
<fdfs_client.fdfs_protol.Tracker_header object at 0x7fc42065ac50>
>>> ret
{'Local file name': '/home/python/Desktop/图片/timg.jpg', 'Storage IP': '192.168.52.128', 'Remote file_id': 'group1/M00/00/00/wKg0gF0TKDiAIwKCAAiHNHphWVQ359.jpg', 'Status': 'Upload successed.', 'Uploaded size': '545.00KB', 'Group name': 'group1'}
>>> 

group1/M00/00/00/’, ‘Status’: ‘Upload successed.’, ‘Uploaded size’: ‘545.00KB’, ‘Group name’: 'group1
Group1:文件上传之后storage组的名称
M00:storage配置的虚拟路径
/00/00/:数据的两级目录,用来存放数据
wKg0gF0TKDiAIwKCAAiHNHphWVQ359.jpg:文件上传之后的名字,
注意点:它和上传的时候已经不一样了.它是由服务器根据特定的信息生成的,
文件名包括:源存储服务器的IP地址,文件创建的时间戳,文件的大小,随机数和文件的扩展名等信息

自定义django文件存储并且保存到FDFS服务器上

Django是自带文件存储系统的,但是默认的文件存储到本地,在本项目中,需要将文件保存到FastDFS服务器上,所以需要自定义文件存储系统。

  • 需要继承自django.core.files.storage.Storage
  • 支持Django不带任何参数来实例化存储类,也就是说任何设置应该从配置django.conf.settings中获取
  • 存储类中必须实现_open()和_save()方法,以及任何后续使用中可能用到的其他方法。

在刚才的fastdfs目录中建一个fdfs_client.py文件用来自定义文件管理

存储类中必须实现open()和save()方法,以及任何后续使用中可能用到的其他方法。

  • def save(self, name=None, content=None, max_length=None): 被Storage.save()调用,name是传入的文件名,content是Django接收到的文件内容,该方法需要将content文件内容保存。Django会将该方法的返回值保存到数据库中对应的文件字段,也就是说该方法应该返回要保存在数据库中的文件名信息

@deconstructible需要加上这个装饰器
您的存储类必须是deconstructible,以便在迁移中的字段上使用它时可以序列化。 只要你的字段有自己的参数可以自动序列化,你可以使用django.utils.deconstruct.deconstructible类装饰器(这是Django在FileSystemStorage上使用的)。

from fdfs_client.client import Fdfs_client
from django.core.files.storage import Storage
from django.conf import settings
from django.utils.deconstruct import deconstructible

@deconstructible
class FastDfsStorage(Storage):
    '''定义FSATDFS客户端'''
    def __init__(self, base_url=None, client_conf=None):
        """
        初始化对象
        :param base_url:将来用构图用,文件等的完整路径
        :param client_conf:fdfs客户端的配置文件完整路径
        """
        if base_url is None:
            base_url = settings.FDFS_URL
        #进行定义
        self.base_url = base_url

        if client_conf is None:
            client_conf = settings.FDFS_CLIENT_CONF
        #进行定义
        self.client_conf = client_conf

    def open(self, name, mode='rb'):
        """
        打开文件
        :param name:
        :param mode:
        :return:
        """
        pass

    def save(self, name=None, content=None, max_length=None):
        """
        保存文件,只需要传入一个name或者content即可
        :param name: 传入文件名
        :param content: 文件内容
        :return:保存到数据库中的FastDFSDE文件名
        """
        # 创建一个客户端对象
        client = Fdfs_client(self.client_conf)
        # 上传文件
        if name is None:
        	# 通过二进制文件上传
            ret = client.upload_by_buffer(content.read())
        else:
        	# 通过文件名上传
            ret = client.upload_by_filename(name)
        #判断上传状态,如果失败,抛错
        if ret.get("Status") != "Upload successed.":
            raise Exception("upload file failed")
        # 如果上传成功,就将Remote file_id 返回给用户
        file_name = ret.get("Remote file_id")
        #  返回
        return file_name

    def exists(self, name):
        """
        检查文件是否重复, FastDFS自动区分重复文件
        :param name:
        :return:
        """
        return False

    def url(self, name):
        """
        获取name文件的完整url
        :param name:
        :return:
        """
        return self.base_url + name


配置默认设置

配置默认的配置在项目的设置文件里(我设置在settings.py中)

# django文件存储
DEFAULT_FILE_STORAGE = 'shanghuishop.fastdfs.fdfs_client.FastDfsStorage'

# FastDFS
FDFS_URL = 'http://image.shanghui.site:8888/'
FDFS_CLIENT_CONF = os.path.join(BASE_DIR, 'fastdfs/client.conf')

如果上面报错,则改为下面配置
错误信息

configparser.NoOptionError: No option 'connect_timeout' in section: '__config__'
# django文件存储
DEFAULT_FILE_STORAGE = 'shanghui.fastdfs.fdfs_client.FastDfsStorage'

# FastDFS
FDFS_URL = 'http://image.shanghui.site:8888/'
LAST_BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
FDFS_CLIENT_CONF = os.path.join(LAST_BASE_DIR, 'fastdfs/client.conf')

配置系统路径

在/etc/hosts中添加访问FastDFS storage服务器的域名

127.0.0.1   image.shanghui.site

测试上传以及文件服务器域名

在项目需要上传的地方导包并使用:

from fastdfs.fdfs_client import FastDfsStorage
    fdfs = FastDfsStorage()
    ret = fdfs.save('/home/python/Desktop/图片/7f6b685a50a15343041d1b5e25646882.jpg')
    print(ret)

上传成功后打开image.shanghui.site:8888/

在这里插入图片描述
显示这样就成功,然后域名加上 ret返回的路径
‘group1/M00/00/00/wKg0gF0TV2WAa5adAAF1aK2LJC8381.jpg’,这个方法返回的路径就可以得到刚刚上传的图片:
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值