Architektur und Design des Bildbettprojekts

Architektur und Design eines verteilten Dateidienstsystems

Das Projekt nutzt verteilte Dateisystem- und Clustertechnologien von FastDFS, um eine einheitliche Schnittstelle zur Bereitstellung von Dateispeicher- und Zugriffsdiensten für die Außenwelt bereitzustellen, sodass Benutzer über das Netzwerk auf Dateiressourcen auf der Serverseite zugreifen können, um die Anforderungen einer massiven Datenspeicherung zu erfüllen

die Architektur

Das Projekt übernimmt das B/S-Modell, der Server interagiert mit dem Browser, wandelt die Operation des Benutzers in eine HTTP-Anfrage um und sendet sie an den Server, verwendet Nginx als Reverse-Proxy-Server auf dem Server, um die Anfrage weiterzuleiten, und den FastCGI-Prozess verarbeitet die entsprechende Anfrage.FastDFS implementiert die verteilte Speicherung von Dateien. Gleichzeitig wird MySQL als Speicher für Projektdateninformationen und Redis als Cache zum Speichern von Sitzungs- und Hot-Daten verwendet.

Bildbeschreibung hier einfügen

System-Design

MySQL-Design

file_info (Dateiinformationstabelle)

Feldname Feldtyp Zwang Feld Beschreibung
Ausweis groß PRIMARY KEY、AUTO_INCREMENT Dateinummer
md5 varchar(256) NICHT NULL Datei md5
file_id varchar(256) NICHT NULL Datei-ID, die dem Dateipfad von FastDFS entspricht
URL varchar(512) NICHT NULL Der vollständige Speicherpfad der Datei: 192.168.52.139:80/group1/M00/00/00/xxx.png
Größe groß Dateigröße (Byte)
Typ varchar(32) Dateityp (png\zip...)
zählen int Anzahl der Dateireferenzen

share_file_list (Liste der freigegebenen Dateien)

Feldname Feldtyp Zwang Feld Beschreibung
Ausweis int PRIMARY KEY、AUTO_INCREMENT Primärschlüssel
Benutzer varchar(32) NICHT NULL Der Benutzer, dem die Datei gehört
md5 varchar(256) NICHT NULL Datei md5
Dateinamen varchar(128) Dateinamen
pv int STANDARD 1 Datei-Downloads
Zeit schaffen Zeitstempel Dateifreigabezeit

user_file_count (Anzahl der Benutzerdateien)

Feldname Feldtyp Zwang Feld Beschreibung
Ausweis int PRIMARY KEY、AUTO_INCREMENT
Benutzer varchar(128) NICHT NULL, EINZIGARTIG Der Benutzer, dem die Datei gehört, die freigegebene Datei
zählen int Anzahl der Dateien im Besitz

user_file_list (Benutzerdateiliste)

Feldname Feldtyp Zwang Feld Beschreibung
Ausweis int PRIMARY KEY、AUTO_INCREMENT
Benutzer varchar(32) NICHT NULL Der Benutzer, dem die Datei gehört
md5 varchar(256) NICHT NULL Datei md5
Zeit schaffen Zeitstempel Dateierstellungszeit
Dateinamen varchar(128) Dateinamen
shared_status int geteilter Zustand
pv int Datei-Downloads

user_info (Benutzerinformationen)

Feldname Feldtyp Feldbeschränkungen Feld Beschreibung
Ausweis int PRIMARY KEY、AUTO_INCREMENT Benutzer-ID
Nutzername varchar(32) EINZIGARTIG, NICHT NULL Nutzername
Spitzname varchar(32) EINZIGARTIG, NICHT NULL Spitzname des Benutzers
Passwort varchar(32) NICHT NULL Passwort
Telefon varchar(16) NICHT NULL Telefonnummer
Email varchar(64) Post
Zeit schaffen Zeitstempel Zeit

Redis-Design

API-Design

项目使用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注册

业务逻辑

Bildbeschreibung hier einfügen

  • 获取请求数据包内容
  • 解析收到的用户注册信息的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写入管道中,父进程读取管道中的内容并回收子进程的资源

Bildbeschreibung hier einfügen

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

获取文件所存放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 befasst sich mit freigegebenen Dateien

nicht teilen

Geschäftslogik

  • Stellen Sie den Dateifreigabestatus in MySQL auf „Keine Freigabe“ ein
  • Fragen Sie die Anzahl der freigegebenen Dateien von Benutzern ab
    • >1, die Anzahl der gemeinsam genutzten Dateien -1, andernfalls löschen Sie die Zeile, die der Anzahl der gemeinsam genutzten Dateien entspricht
  • Löschen Sie den entsprechenden Datensatz in der Liste der freigegebenen Dateien
  • Löschen Sie den entsprechenden Dateieintrag in Redis
Dump-Datei

Geschäftslogik

  • Abfrage, ob die Datei bereits in der Benutzerdateiliste in MySQL vorhanden ist
  • Ergebnis zurückgeben, falls vorhanden
  • Wenn es nicht existiert, erhöhen Sie den Verweiszähler der entsprechenden Datei in der Dateiliste und erhöhen Sie den entsprechenden Datensatz in der Benutzerdateiliste und aktualisieren Sie die Anzahl der Benutzerdateien
Laden Sie freigegebene Dateien herunter

Geschäftslogik

  • Aktualisieren Sie die Anzahl der Downloads der entsprechenden Datei in MySQL
  • Aktualisieren Sie den entsprechenden Dateidatensatz in Redis

sharepicture_cgi.c verwaltet das Teilen von Bildern

Bild teilen

Geschäftslogik

  • Extraktionscode generieren: MD5 (Benutzername, Datei MD5, Zufallszahl)
  • Fügen Sie den Extraktionscode und die Datei MD5 in die Datenbank ein und aktualisieren Sie gleichzeitig die Anzahl der freigegebenen Bilder
  • Geben Sie den Extraktionscode an den Benutzer zurück

Ich denke du magst

Origin blog.csdn.net/blll0/article/details/128027668
Empfohlen
Rangfolge