图床项目架构与设计

news2025/8/10 3:28:16

分布式文件服务系统架构与设计

该项目利用FastDFS分布式文件系统以及集群等技术提供统一的接口对外提供文件存储和访问服务,使用户能够通过网络访问服务端的文件资源,满足海量数据存储的需求

架构

项目采用B/S模型,服务端与浏览器进行交互,将用户的操作转换为HTTP请求发送给服务端,在服务端使用Nginx作为反向代理服务器进行请求转发,由FastCGI进程处理对应的请求,FastDFS实现文件的分布式存储。同时使用MySQL作为项目数据信息的存储,Redis作为缓存存储session与热点数据。

在这里插入图片描述

系统设计

MySQL设计

file_info(文件信息表)

字段名字段类型约束字段说明
idbigintPRIMARY KEY、AUTO_INCREMENT文件序号
md5varchar(256)NOT NULL文件md5
file_idvarchar(256)NOT NULL文件id,对应FastDFS的文件路径
urlvarchar(512)NOT NULL文件的完整存储路径:192.168.52.139:80/group1/M00/00/00/xxx.png
sizebigint文件大小(字节)
typevarchar(32)文件类型(png\zip…)
countint文件引用计数

share_file_list(共享文件列表)

字段名字段类型约束字段说明
idintPRIMARY KEY、AUTO_INCREMENT主键
uservarchar(32)NOT NULL文件所属用户
md5varchar(256)NOT NULL文件md5
file_namevarchar(128)文件名
pvintDEFUALT 1文件下载量
create_timetimestamp文件共享时间

user_file_count(用户文件数量)

字段名字段类型约束字段说明
idintPRIMARY KEY、AUTO_INCREMENT
uservarchar(128)NOT NULL、UNIQUE文件所属用户、共享的文件
countint拥有的文件数量

user_file_list(用户文件列表)

字段名字段类型约束字段说明
idintPRIMARY KEY、AUTO_INCREMENT
uservarchar(32)NOT NULL文件所属用户
md5varchar(256)NOT NULL文件md5
create_timetimestamp文件创建时间
file_namevarchar(128)文件名
shared_statusint共享状态
pvint文件下载量

user_info(用户信息)

字段名字段类型字段约束字段说明
idintPRIMARY KEY、AUTO_INCREMENT用户id
user_namevarchar(32)UNIQUE、NOT NULL用户名称
nick_namevarchar(32)UNIQUE、NOT NULL用户昵称
passwordvarchar(32)NOT NULL密码
phonevarchar(16)NOT NULL手机号码
emailvarchar(64)邮箱
create_timetimestamp时间

Redis设计

API设计

项目使用FastCGI进程处理对应的请求,FastCGI会一直阻塞等待客户端连接,当有客户端连接到来的时候就获取连接以及判断数据包是否合法,如果合法就解析数据进行业务处理,否则输出错误。

//阻塞等待用户连接
while (FCGI_Accept() >= 0) {
    // 获取数据包内容长度
    char *contentLength = getenv("CONTENT_LENGTH");
    int len;

    printf("Content-type: text/html\r\n\r\n");
	
    if( contentLength == NULL ) {
        len = 0;
    } else {
        len = atoi(contentLength); //字符串转整型
    }
	
    // 没有请求相关信息
    if (len <= 0) {
        printf("No data from standard input.<p>\n");
        LOG(REG_LOG_MODULE, REG_LOG_PROC, "len = 0, No data from standard input\n");
    } else {
        // 解析数据包进行业务处理
    }

reg_cgi.c注册

业务逻辑

在这里插入图片描述

  • 获取请求数据包内容
  • 解析收到的用户注册信息的json数据包得到注册用户的相关信息(用户名、密码、邮箱等)
  • 查询数据库判断用户是否存在,如果存在则将注册状态设置为失败,否则向数据库中插入新用户记录同时将注册状态设置为成功
  • 根据注册状态是否成功将信息返回给用户

login_cgi.c登录

业务逻辑

  • 获取请求数据包内容
  • 解析收到的用户注册信息的json数据包得到用户名和密码
  • 通过数据库查询判断用户名与密码是否正确,如果错误则将登录状态设置为失败;否则生成token存储到Redis中,并将登录状态设置为成功
  • 根据登录状态是否成功将相关信息返回给用户

token

相当于令牌,是服务端生成的一个字符串,用于验证客户端的身份,不需要在服务端存储用户的登录记录

流程:

  • 客户端使用用户名和密码进行登录
  • 登录成功后服务端根据一定的规则生成一个token并保存,同时将token发送给客户端
  • 客户端收到token后也保存起来
  • 后续客户端发送请求的时候就带上token
  • 服务端收到请求验证token是否合法,如果合法就继续请求

生成规则:生成4个随机数并对随机数进行加密,再将加密后的随机数进行base64编码,最后转换为定长的MD5

服务端将token保存在Redis中同时设置有效期(24小时),key为用户名,value为token

base64

使用64个字符表示任意二进制数据的方法,防止不可见的编码

二进制文件中可能存在很多无法显示和打印的字符,这些字符在网络中传输的过程中经过的不同设备处理方式可能不同,导致不可见的字符可能被错误处理

需要先对数据进行编码转换为可见的字符(比如ASCII码)保证数据的可靠传输

Base64将每三个8bit的字节转换为四个6bit的字节,再在6bit添两位高位0组成四个8bit的字节,转换后的字符串比原来要长1/3

md5_cgi.c\upload_cgi.c上传文件

每个文件都有一个唯一的MD5值用于唯一的标识文件

客户端在上传文件之前将文件的MD5上传到服务器上,服务器判断是否已经存在MD5:如果存在说明文件已经存在无需再上传;如果不存在才真正上传文件

md5_cgi.c秒传文件

业务逻辑

  • 获取请求数据包内容
  • 进行收到的文件上传信息的json数据包得到token和MD5
  • 验证token信息,如果验证失败则给用户返回错误信息;否则进行文件上传处理
  • 通过数据库查询MD5对应文件是否存在
    • 如果存在
      • 通过数据库查询用户是否已经有此文件,如果有则上传成功
      • 如果没有则将文件引用计数+1,同时向数据库中用户文件列表插入记录表示用户上传了某个文件,同时将用户文件数量表用户对应数量+1
  • 根据上传状态是否成功将相关信息返回给用户

对于用户来说MD5+文件名一样才是重复的文件,但是对于FastDFS来说MD5一样就是重复的文件

upload_cgi.c上传文件

业务逻辑

  • 获取上传文件相关信息并保存到本地临时文件中(文件上传者、文件名、文件大小等)
  • 将文件存储到FastDFS中并得到文件的file_id
  • 删除本地临时存放的上传文件
  • 获取文件所存放storaged的host_name并拼接处完整的HTTP地址
  • 将文件信息存储到数据库中
  • 根据上传状态是否成功将相关信息返回给用户

upload_to_dstorage将文件上传到FastDFS中

采用多进程方式,通过匿名管道在父子进程之间传输数据。由子进程读取本地临时文件中的内容上传到FastDFS中,获取到file_id写入管道中,父进程读取管道中的内容并回收子进程的资源

在这里插入图片描述

为什么采用多进程方式:防止上传文件过程中发生错误导致进程崩溃进而导致整个上传文件系统崩溃;采用多进程方式子进程在上传文件过程中崩溃了父进程还可以获取子进程崩溃信息等,不会影响到父进程,避免系统不可用

获取文件所存放storaged的host_name并拼接处完整的HTTP地址

采用多进程方式,通过匿名管道在父子进程之间传输数据

子进程利用fdfs_file_info进程读取文件的详细存储信息,获取storage的host_name并写入管道中

父进程读取管道中的信息拼接出完整的HTTP地址

myfiles_cgi.c获取用户文件列表

业务逻辑

  • 获取URL地址"?"后面的cmd命令
  • 根据不同的cmd命令执行不同的请求
    • count获取文件个数
      • 验证token
      • 通过数据库查询用户文件个数
    • 获取用户文件信息
      • 验证token
      • pvasc按下载量升序
      • pvdesc按下载量降序
  • 将查询到的结果返回给用户

sharefiles_cgi.c获取分享文件

获取共享文件个数

  • 获取URL地址"?"后面的cmd=count
  • 通过数据库查询用户文件个数

获取共享文件列表

  • 获取URL地址"?"后面的cmd=normal
  • 通过数据库查询用户分享文件列表

获取共享文件排行榜

  • MySQL中共享文件数量和Redis共享文件数量对比,判断是否相等
  • 如果不相等则清空Redis数据,从MySQL中导入数据到Redis中
  • 从Redis读取数据并将相应信息返回给用户

dealfile_cgi.c文件处理

删除文件

业务逻辑

  • 判断文件是否已经分享
    • 文件标识:MD5+文件名
    • 首先在Redis的文件分享列表中查询是否有对应的文件,如果有说明已经分享该文件了
    • 如果Redis中没有则到MySQL中查询,如果MySQL中查询用户是否有该文件
  • 如果文件已经被分享则在MySQL中删除用户分享该文件的对应记录,同时共享文件数量-1,并在Redis中移除相应记录的信息(分享文件列表、文件hash)
  • 在MySQL中删除用户文件列表的数据并使用户文件数量-1
  • 当文件引用计数为0时在storage中删除此文件
分享文件

业务逻辑

  • 判断此文件是否已经分享了
    • 文件标识:MD5+文件名
    • 首先在Redis的文件分享列表中查询是否有对应的文件,如果有说明已经分享该文件了,直接给用户返回结果
    • 如果Redis中没有则到MySQL中查询该文件是否已经分享
      • 如果有则在Redis中记录该文件的分享信息
    • 如果没有则在在MySQL中更新文件状态已经共享文件数量,同时在Redis中记录该文件的分享信息
更新文件下载计数
  • 查询文件下载计数同时更新

dealsharefile_cgi.c处理分享文件

取消分享

业务逻辑

  • 在MySQL中将文件分享状态设置为不分享
  • 查询用户共享文件数量
    • >1则共享文件数量-1,否则删除共享文件数量对应的行
  • 删除共享文件列表中对应的记录
  • 在Redis中删除对应文件记录
转存文件

业务逻辑

  • 在MySQL中查询用户文件列表中是否已经存在该文件
  • 如果存在则返回结果
  • 如果不存在则在文件列表中增加对应文件的引用计数,同时用户文件列表中增加对应的记录,更新用户文件数量
下载共享文件

业务逻辑

  • 在MySQL中更新对应文件的下载次数
  • 在Redis中更新对应文件记录

sharepicture_cgi.c处理图片分享

图片分享

业务逻辑

  • 生成提取码:MD5(用户名、文件MD5、随机数)
  • 将提取码和文件MD5插入数据库中同时更新分享图片数量
  • 向用户返回提取码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/33963.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论文阅读-Detecting and Recovering Sequential DeepFake Manipulation(SeqFakeFormer)

一、论文信息 论文名称&#xff1a;Detecting and Recovering Sequential DeepFake Manipulation&#xff08;篡改序列检测还原&#xff09; 论文链接: https://arxiv.org/pdf/2207.02204.pdf 项目主页: https://rshaojimmy.github.io/Projects/SeqDeepFake GitHub: https:…

Linux 最近学习总结

Linux 最近学习总结一.基础命令一.基础命令 基础命令就像是锤子、螺丝刀、锯等木匠常用到的工具&#xff0c;也是我们每天都会用到的命令 1.ls 列出当前所在目录的内容 2.ls 文件夹名 列出其他文件夹内容 3.ls ~ 其中~代表home目录 4.ls ~/Desktop/Java电子书/*.pdf 使用…

Eigen Segmentation fault (core dumped)

不会GDB吃大亏问题描述&#xff1a;解法&#xff1a;写在前面的话&#xff1a;我是PCL新手。也是Cmake新手。Eigen有点折腾人。 问题描述&#xff1a; 在调用PCL库实现一些有趣的功能&#xff0c;考虑到考虑到兼容不同平台&#xff0c;现状如下&#xff1a; VS2015&#xff1…

JavaScript基本语法详解

目录 一、JavaScript数据类型 二、算术运算符 1&#xff1a;分支结构 &#xff08;1&#xff09;if语句 &#xff08;2&#xff09;if...else语句 &#xff08;3&#xff09;if..else if语句 2&#xff1a;循环结构 &#xff08;1&#xff09;for循环 &#xff08;2&a…

ipv6地址概述——了解ipv6地址

个人简介&#xff1a;云计算网络运维专业人员&#xff0c;了解运维知识&#xff0c;掌握TCP/IP协议&#xff0c;每天分享网络运维知识与技能。个人爱好: 编程&#xff0c;打篮球&#xff0c;计算机知识个人名言&#xff1a;海不辞水&#xff0c;故能成其大&#xff1b;山不辞石…

[ Linux ] 进程间通信之共享内存

在上篇博文我们了解了通过管道完成进程间通信&#xff0c;我们了解匿名管道和命名管道&#xff0c;并且通过编码模拟实现使用了匿名管道和命名管道。我们知道要让进程间完成通信必须让这两个进程首先看到同一份资源&#xff0c;因此给予这个前提&#xff0c;本篇博文我们了解另…

【Linux】自动化构建工具-make/Makefile第一个小程序

大家好我是沐曦希&#x1f495; 文章目录一.项目自动化构建工具-make/Makefile1.背景2. 举例3. 原理4. 总结5. 项目清理6. 习题习题一习题二二.第一个小程序&#xff0d;进度条1.行缓冲区2.倒计时3.进度条一.项目自动化构建工具-make/Makefile 1.背景 会不会写makefile&#x…

使用 elasticdump 跨版本迁移 ES 数据

1、elasticdump 用途介绍 elasticdump 是一个在 Github 开源的 Elasticsearch 的数据迁移工具&#xff0c;项目 Github 地址&#xff1a;[传送门](Github 地址&#xff1a;https://github.com/elasticsearch-dump/elasticsearch-dump) elasticdump 支持跨版本导出和导入数据&am…

【java进阶07:常用类】String类、包装类、日期类Date、数字类、随机数、枚举类型

String类 String类型的字符串存储原理 /*关于java JDK中内置的一个类&#xff1a;java.util.String1、String表示字符串类型&#xff0c;属于引用数据类型&#xff0c;不属于基本数据类型。2、在java中随便使用双引号括起来的都是String对象&#xff0c;例如&#xff1a;"…

零基础上手unity VR开发【配置PC端项目的实时调试】

&#x1f4cc;个人主页&#xff1a;个人主页 ​&#x1f9c0; 推荐专栏&#xff1a;Unity VR 开发成神之路 --【着重解决VR项目开发难&#xff0c;国内资料匮乏的问题。从零入门&#xff0c;一步一个脚印&#xff0c;带你搞定VR开发! &#x1f63b;&#x1f63b;】 &#x1f4d…

聊一聊如何截获 C# 程序产生的日志

一&#xff1a;背景 1.讲故事 前段时间分析了一个dump&#xff0c;一顿操作之后&#xff0c;我希望用外力来阻止程序内部对某一个com组件的调用&#xff0c;对&#xff0c;就是想借助外力实现&#xff0c;如果用 windbg 的话&#xff0c;可以说非常轻松&#xff0c;但现实情况…

当下互联网行业趋势,你顶得住吗?

持续三年的疫情导致经济形式大不如前&#xff0c;特别是互联网行业&#xff0c;不少员工面临着失业的压力&#xff0c;在如此恶劣的大环境下&#xff0c;计算机行业的我们应该如何生存&#xff1f;有一个很好的办法就是 —— 考证&#xff01;&#xff01;&#xff01;如今越来…

多线程与并发 - 常见的几种锁的实现方式

1、悲观锁 正如其名&#xff0c;它是指对数据修改时持保守态度&#xff0c;认为其他人也会修改数据。因此在操作数据时&#xff0c;会把数据锁住&#xff0c;直到操作完成。悲观锁大多数情况下依靠数据库的锁机制实现&#xff0c;以保证操作最大程度的独占性。如果加锁的时间过…

深度学习入门(6)误差反向传播基础---计算图与链式法则

在我的第三篇博文《深度学习入门&#xff08;3&#xff09;神经网络参数梯度的计算方式》中详细介绍了通过微分方式计算神经网络权重参数的梯度。但是数值微分的方式计算梯度效率较低。后续博文会介绍另外一种更加高效的梯度计算方式---误差的反向传播。 这篇文章介绍的是误差…

CorelDRAW2023最新版矢量设计软件

CorelDRAW2023最新版是我比较用的比较好的一款软件&#xff0c;因为其作为一款优秀的矢量设计软件&#xff0c;兼具功能和性能&#xff0c;它是由Corel公司出品的矢量设计工具&#xff0c;被广泛应用于排版印刷、矢量图形编辑、网页设计等行业。CDR软件的优势在于&#xff1a;易…

ROS2 机器人操作系统入门和安装以及如何使用 .NET 进行开发

本文是 ROS2 入门的第一课&#xff0c;简单介绍了 ROS 系统&#xff0c;并演示了 ROS2 系统在 Ubuntu 22.04 中的安装&#xff08;使用 gitee 和清华源&#xff09;以及其中错误的解决。最后对其优势进行总结&#xff0c;为什么选择 ROS。最后介绍简单 Demo 和如何使用 .NET 接…

ThingsBoard源码解析-规则引擎

描述 规则引擎是Thingsboard的核心部分&#xff0c;基于Actor编程模型&#xff0c;类似事件驱动&#xff1b; 每个actor都有自己的消息队列&#xff08;mailBox&#xff09;保存接收到的消息 actor可以创建actor actor可以将消息转发给其他actor 分析 Actor模型实现 系统…

戴尔科技集团通过多云数据保护和安全创新增强网络弹性

中国北京——2022年11月18日 Dell PowerProtect Data Manager软件更新和新一代备份一体机可帮助客户提高运维安全和网络弹性 戴尔多云数据保护解决方案利用内置的安全运维功能加速采用零信任原则 2022年全球数据保护指数(GDPI)调查结果公布 戴尔科技集团(NYSE:Dell)扩大其在数据…

OA系统,有效提升企业办公效率落实执行力

企业管理的成功将最终取决于企业的执行情况&#xff0c;只要有良好的经营管理&#xff0c;管理系统&#xff0c;一个好的领导者&#xff0c;充分调动员工的积极性&#xff0c;将能最大限度的管理执行力。 OA协同办公系统提供了工作流和协同工作互补结合。工作流程严格规定了工作…

PCB铺铜的优点与缺点

PCB设计铺铜是电路板设计的一个非常重要的环节。 什么是PCB铺铜&#xff0c;就是将PCB上无布线区域闲置的空间用固体铜填充。铺铜的意义在于减小地线阻抗&#xff0c;提高抗干扰能力;降低压降&#xff0c;提高电源效率&#xff0c;与地线相连&#xff0c;还可以减小环路面积。 …