云备份项目--服务端编写

news2025/1/8 4:53:28

文章目录

  • 7. 数据管理模块
    • 7.1 如何设计
    • 7.2 完整的类
  • 8. 热点管理
    • 8.1 如何设计
    • 8.2 完整的类
  • 9. 业务处理模块
    • 9.1 如何设计
    • 9.2 完整的类
    • 9.3 测试
      • 9.3.1 测试展示功能

完整的代码–gitee链接

7. 数据管理模块

TODO: 读写锁?普通锁?

7.1 如何设计

需要管理哪些数据

  • 文件大小
  • 文件最后一次修改时间
  • 文件最后一次访问时间
  • 文件的实际存放路径
  • 文件是否被压缩
  • 文件压缩包存放路径
  • url的资源路径path(URL路径(如http://www.example.com/path/to/file的路径path就是是/path/to/file

如何管理数据

  • 用于数据信息访问:使用哈希表,使用urlPath作为key
  • 使用json序列化将信息保存在文件中
  • 读写锁,为了提高访问效率

7.2 完整的类

/* 文件管理数据模块, 这里有文件的所有信息
, 用到了JsonUtil.hpp, FileUtil.hpp, Config.hpp */

#ifndef __MY_DATA_MANGER__
#define __MY_DATA_MANGER__
#include "Config.hpp"
#include <iostream>
#include <unordered_map>
#include <pthread.h>
#include <string>
#include <vector>
#include <mutex>

namespace cloud
{
struct BackupInfo
{   
    // 传入文件名, 初始化结构体
    BackupInfo(const std::string& fileName);

    BackupInfo(); 

    // 当前文件的状态是否ok, ok 返回true
    bool isOk();

    bool isPacked;              // 文件是否被压缩(true表示被压缩了)
    size_t fileSz;              // 文件大小
    time_t lastMTime;           // 文件最后一次修改时间
    time_t lastATime;           // 文件最后一次访问时间
    std::string ulFilePath;     // 上传文件存放的路径(这里要精确到哪个路径下哪个文件,如./files/fileName.txt)
    std::string rarFilePath;    // 压缩文件存放的路径(这里要精确到哪个路径下哪个文件,如./rars/fileName.lz)
    std::string urlPath;        // url的资源路径path
    bool biStatus = true;       // 当前文件的状态是否ok
private:
    // 构造函数使用该函数
    bool init(const std::string& fileName);
};

class DataManager
{
private:
    std::unordered_map<std::string, BackupInfo> _hash;       // 通过key:url来映射BackupInfo
    std::string _backup;                                     // 备份的信息文件的路径
    pthread_rwlock_t _rwlock;
    std::mutex _mtx;
public:
    DataManager();

    // 将bi添加到哈希表中
    bool insertInfo(const BackupInfo& bi);

    // 根据bi修改哈希表中的值
    bool updateInfo(const BackupInfo& bi); 

    // 通过urlPath获得一个文件信息, 放到info中
    bool get1FromURL(const std::string& urlPath, BackupInfo* info);

    // 通过该文件的路径(本地路径)获得文件信息, 放到info中
    bool get1FromPath(const std::string& path, BackupInfo* info);

    // 获取所有文件信息, 放到数组中
    bool getAllInfo(std::vector<BackupInfo>* vBi);

    // 保存备份文件, 将所有文件的信息保存下来
    bool strorageBackup();

    // 加载配置文件, 将其放到_hash中
    bool loadBackup();
};
}
#endif

8. 热点管理

8.1 如何设计

需要完成的功能: 对服务器上备份的文件进行检测,哪些文件长时间没有被访问,则认为是非热点文件,则压缩存储,节省磁盘空间。

  1. 遍历所有的文件
  2. 检测文件的最后一次访问时间
  3. 与当前时间进行相减得到差值,这个差值如果大于设定好的非热点判断时间则认为是非热点文件,则进行压缩存放到压缩路径中,删除源文件
  4. 修改数据管理模块对应的文件信息(压缩标志–>true)

8.2 完整的类

/* 
热点管理模块, 
检测压缩文件存放的路径中所有的文件是否长时间未访问, 
并做相应的压缩处理。
*/
#ifndef __MY_HOTSPOT__MANAGER__
#define __MY_HOTSPOT__MANAGER__
#include "DataManager.hpp"
#include "Config.hpp"
#include <time.h>
#include <unistd.h>

extern cloud::DataManager* dm;
namespace cloud
{
class HotspotManager
{
private:
    std::string _ulPath;      // 上传文件存放的路径(这里指的是文件夹)
    std::string _rarPath;     // 压缩文件存放的路径(这里指的是文件夹)
    std::time_t _hotTime;     // 热点时间
public:
    HotspotManager();

    ~HotspotManager();

    // 提供主要功能: 检测是否是热点+非热点删除并压缩+更改配置文件信息
    bool runHotspotManager();

private:
    // 检测是否是热点文件, 是返回true
    bool checkHot(const std::string& path);

    // 将文件压缩到指定位置
    bool compressAndMov(const std::string& path, cloud::FileUtil& fu);

    // 删除文件
    bool removeFile(cloud::FileUtil& fu);

    // 更新文件的信息, 并进行持久化操作
    bool updateAndStorage(const std::string& path);
};

} 

#endif

9. 业务处理模块

9.1 如何设计

  1. 搭建网络通信服务器:借助httplib完成
  2. 业务请求处理
    1. 文件上传请求:备份客户端上传的文件,响应上传成功
    2. 文件列表展示请求:客户端浏览器请求一个备份文件的展示页面,响应页面
    3. 文件下载请求:通过展示页面,点击下载,响应客户端要下载的文件数据

前置知识:

ETag:

HTTP中的ETag(Entity Tag)是一个与特定版本的资源相关的标识符。它是一种机制,用于确定客户端缓存的副本是否是最新的。

客户端第一次下载文件的时候,会收到这个响应信息,第二次下载,就会将这个信息发送给服务器,想要让服务器根据这个唯一标识判断
这个资源有没有被修改过,如果没有被修改过,直接使用原先缓存的数据,不用重新下载了

Accept-Ranges:

Accept-Ranges允许客户端在下载过程中恢复中断的下载,或者只下载资源的一部分,这可以提高下载效率,尤其是在处理大文件时。其值设置为bytes表示服务器支持基于字节的请求


断点续传

第一次请求:

  1. 客户端发起 HTTP GET 请求一个文件。
  2. 服务器处理请求,返回文件内容以及相应的 Header,其中包括 Etag(例如:627-4d648041f6b80)(假设服务器支持 Etag 生成并已开启了 Etag)状态码为 200。

第二次请求(断点续传):

  1. 客户端发起 HTTP GET 请求一个文件,同时发送 If-Range(该头的内容就是第一次请求时服务器返回的 Etag:627-4d648041f6b80)。
  2. 服务器判断接收到的 Etag 和计算出来的 Etag 是否匹配,如果匹配,那么响应的状态码为 206;否则,状态码为 200。
请求
GET /download/a.txt http/1.1
Content-Length: 123
If-Range: "⽂件唯⼀标识"		服务端在下载时响应的etag字段”用于服务端判断这个文件与原先下载的文件是否一致
Range: bytes=89-999			这个字段用于告诉服务器客户端需要的数据区间范围

响应
HTTP/1.1 206 Partial Content
Content-Length:123
Content-Range: bytes 89-999/100000
Content-Type: application/octet-stream
ETag: "inode-size-mtime⼀个能够唯⼀标识⽂件的数据"
Accept-Ranges: bytes

9.2 完整的类

/* 提供业务处理的功能, 处理来自客户端的各种请求 */
#ifndef __MY_SERVICE__
#define __MY_SERVICE__
#include "DataManager.hpp"
#include "httplib.h"

extern cloud::DataManager* dm;         // 用于管理数据

namespace cloud
{
class Service
{
private:
    int _srvPort;                    // 服务器端口号
    std::string _srvIp;              // 服务器ip
    std::string _urlDownPre;         // url下载路径前缀
public:
    Service();

    ~Service();

    // 进行业务处理
    void runService();

private:
    // 处理上传文件
    static void uploadHandler(const httplib::Request& req, httplib::Response& rsp);

    // 处理下载文件
    static void downloadHandler(const httplib::Request& req, httplib::Response& rsp);

    // 处理显示操作
    static void listHandler(const httplib::Request& req, httplib::Response& rsp);

    // 将时间戳转换为可读的
    static std::string timeToStr(time_t t);

    // 获取ETag, 文件名-文件大小-最后一次修改时间
    static std::string getETag(const BackupInfo& bi);
};
}
#endif

9.3 测试

9.3.1 测试展示功能

此时的backup.data如下

[
	{
		"fileSz" : 0,
		"isPacked" : false,
		"lastATime" : 1735651729,
		"lastMTime" : 1735651729,
		"rarFilePath" : "./rars/testtest.txt.lz",
		"ulFilePath" : "./files/testtest.txt",
		"urlPath" : "/download/testtest.txt"
	},
	{
		"fileSz" : 3083,
		"isPacked" : false,
		"lastATime" : 1735649756,
		"lastMTime" : 1735131288,
		"rarFilePath" : "./rars/Config.hpp.lz",
		"ulFilePath" : "./files/Config.hpp",
		"urlPath" : "/download/Config.hpp"
	}
]

页面显示如下

image-20241231213014354

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

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

相关文章

Flink operator实现自动扩缩容

官网文档位置&#xff1a; 1.Autoscaler | Apache Flink Kubernetes Operator 2.Configuration | Apache Flink Kubernetes Operator 1.部署K8S集群 可参照我之前的文章k8s集群搭建 2.Helm安装Flink-Operator helm repo add flink-operator-repo https://downloads.apach…

使用LINUX的dd命令制作自己的img镜像

为了避免重复安装同一镜像&#xff0c;配置环境&#xff0c;首先我准备一个正常使用的完整系统。 使用Gparted软件先将母盘&#xff08;如U盘&#xff0c;TF卡&#xff09;分区调整为只有数据的大小。如&#xff1a;60G的TF卡&#xff0c;只用了3.5G&#xff0c;将未使用的空间…

【Unity3D】LOD Group 多细节层次(CrossFade淡出淡入效果)

新建一个空物体挂载LOD Group脚本 LOD0&#xff08;球体&#xff09; LOD1&#xff08;立方体&#xff09; LOD2&#xff08;单面板Quad&#xff09; 可发现我勾选了Cross Fade并没有渐隐效果&#xff0c;是因为Shader是不透明的&#xff0c;不支持。 经过如下修改后支持Cros…

【2025年最新】OpenWrt 更换国内源的指南(图形界面版)

在上一篇文章中我们讲解了如何使用命令行更换国内源&#xff0c;如果你没有终端工具&#xff0c;或者不喜欢命令行&#xff0c;那么图形界面方式将会是更简单有效的方式。 命令行版本&#xff1a;【2025年最新】OpenWrt 更换国内源的指南(命令行)-CSDN博客 为什么选择通过图形…

Jdk动态代理源码缓存优化比较(JDK17比JDK8)

目录 JDK 8的缓存实现 JDK 17的缓存实现 优化比较 总结实际应用影响 JDK 8的缓存实现 // JDK 8 private static final WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache new WeakCache<>(new KeyFactory(), new ProxyClassFact…

移动电商的崛起与革新:以开源AI智能名片2+1链动模式S2B2C商城小程序为例的深度剖析

摘要&#xff1a;本文旨在探讨移动电商的崛起背景、特点及其对传统电商模式的革新影响&#xff0c;并以开源AI智能名片21链动模式S2B2C商城小程序为具体案例&#xff0c;深入分析其在移动电商领域的创新实践。随着移动互联网技术的飞速发展&#xff0c;移动电商已成为电商行业的…

【计算机网络】课程 实验三 跨交换机实现 VLAN 间路由

实验 3 跨交换机实现 VLAN 间路由 一、实验目的 1&#xff0e;理解跨交换机之间VLAN的特点。 2&#xff0e;掌握如何在交换机上划分基于端口的VLAN&#xff0c;给VLAN内添加端口。 3&#xff0e;利用三层交换机跨交换机实现 VLAN 间路由。 二、实验分析与设计 【背景描述…

计算机网络——数据链路层-介质访问控制

一、介质访问控制方法 在局域网中, 介质访问控制(medium access control)简称MAC&#xff0c;也就是信道访问控制方法&#xff0c;可以 简单的把它理解为如何控制网络节点何时发送数据、如何传输数据以及怎样在介质上接收数据&#xff0c; 是解决当局域网中共用信道的使用产生竞…

121.【C语言】数据结构之快速排序(未优化的Hoare排序存在的问题)以及时间复杂度的分析

目录 1.未优化的Hoare排序存在的问题 测试代码 "量身定制"的测试代码1 运行结果 "量身定制"的测试代码2 运行结果 "量身定制"的测试代码3 运行结果 分析代码1、2和3栈溢出的原因 排有序数组的分析 分析测试代码1:给一个升序数组,要求排…

【操作系统不挂科】操作系统期末考试卷<2>(单选题&简答题&计算与分析题&程序分析题&应用题)

前言 大家好吖&#xff0c;欢迎来到 YY 滴 操作系统不挂科 系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 本章为系列题库&#xff0c;其他章节看下面传送门其他博客 【操作系统不挂科】&#xff1c;操作系统概论&#xff08;1&#xff09;&#xff1e…

解密人工智能:如何改变我们的工作与生活

引言&#xff1a;AI崛起背后的思考 在过去的几十年里&#xff0c;人工智能&#xff08;AI&#xff09;从科幻小说中的神秘存在&#xff0c;逐渐走进了我们的日常生活。无论是智能手机的语音助手&#xff0c;还是推荐心仪商品的电商平台&#xff0c;AI技术已悄然融入工作与生活的…

LLM - 使用 LLaMA-Factory 部署大模型 HTTP 多模态服务 教程 (4)

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/144881432 大模型的 HTTP 服务,通过网络接口,提供 AI 模型功能的服务,允许通过发送 HTTP 请求,交互大模型,通常基于云计算架构,无需在本地部署复杂的模型和硬件,…

Chapter 1 Understanding Large Language Models

文章目录 Understanding Large Language ModelsWhat is an LLM?Applications of LLMSStages of building and using LLMsUsing LLMS for different tasksA closer look at the GPT architectureBuilding a large language modelSummary Understanding Large Language Models …

游戏社交趋势下,游戏语音再升级!

如今&#xff0c;游戏已成为我们社交生活的一个重要娱乐方式&#xff0c;春节临近&#xff0c;与亲朋好友一起畅玩“开黑”无疑是节假日的一大乐趣。在游戏社交互动中&#xff0c;“游戏语音”不可或缺。在传统游戏语音领域&#xff0c;多人在线游戏如 MOBA、FPS 和 MMORPG 的实…

CTFshow—远程命令执行

29-35 Web29 代码利用正则匹配过滤了flag&#xff0c;后面加了/i所以不区分大小写。 可以利用通配符绕过 匹配任何字符串&#xff0f;文本&#xff0c;包括空字符串&#xff1b;*代表任意字符&#xff08;0个或多个&#xff09; ls file * ? 匹配任何一个字符&#xff08;不…

Elasticsearch 入门教程

掌握Elasticsearch&#xff1a;从入门到入门 一、ES 背景1.1 ElasticSearch 的背景1.2 ElasticSearch 的应用场景 二、ES 简介2.1 ElasticSearch 简介2.2 ElasticSearch 的定义与特点2.3 ElasticSearch 与传统数据库的区别2.4 ElasticSearch 的优势和劣势 三、ES 的核心概念3.1…

【Vue学习】Vue 组件实例的生命周期(四个阶段,八个钩子)

一、为什么要理解生命周期&#xff1f; 理解生命周期就像是知道了一部电影的剧情走向&#xff0c;能让你在适当的时机做出反应。Vue 生命周期的钩子让你可以在不同的阶段插入你的逻辑&#xff0c;像是提前准备、后期清理或者在数据更新时做点事情。这种“精确控制”的能力会让你…

【Vim Masterclass 笔记08】第 6 章:Vim 中的文本变换及替换操作 + S06L20:文本的插入、变更、替换,以及合并操作

文章目录 Section 6&#xff1a;Transforming and Substituting TextS06L21 Inserting, Changing, Replacing, and Joining1 定位到行首非空字符&#xff0c;并启用插入模式2 在紧挨光标的下一个字符位置启动插入模式3 定位到一行末尾&#xff0c;并启用插入模式4 定位到光标的…

vip与haproxy构建nginx高可用集群传递客户端真实ip

问题 系统使用了vip与haproxy实现高可用以及对nginx进行负载均衡&#xff0c;但是发现在上游的应用服务无法拿到客户端的请求ip地址&#xff0c;拿到的是主haproxy机器的ip&#xff0c;以下是nginx与haproxy的缩减配置&#xff1a; location ~* ^/(xx|xx) {proxy_pass http:/…

YOLOv5部署到web端(flask+js简单易懂)

文章目录 前言最终实现效果图后端实现 主界面检测函数检测结果显示 前端实现 主界面(index.html&#xff09;显示图片界面 总结 前言 最近&#xff0c;老板让写一个程序把yolov5检测模型部署到web端&#xff0c;在网页直接进行目标检测。经过1个星期的努力&#xff0c;终于实…