当前位置: 首页 > article >正文

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

文章目录

  • 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.kler.cn/a/467944.html

相关文章:

  • 【C++】字符串与字符数|组操作详解:strcpy 和 strcat 的使用与解析
  • vue3组件化开发优势劣势分析,及一个案例
  • 软件项目体系建设文档,项目开发实施运维,审计,安全体系建设,验收交付,售前资料(word原件)
  • Rocketmq 探索MQClientFactoryScheduledThread线程工作
  • rk3568 上Qt5.12.12迁移问题解决
  • 百度Android最新150道面试题及参考答案 (中)
  • Oracle 11g rac + Dataguard 环境调整 redo log 大小
  • React虚拟DOM:理解和应用
  • torch.reciprocal介绍
  • 游戏引擎学习第70天
  • 面试题解,Java中的“对象”剖析
  • 【js引擎】quickjs 中的两个 proto
  • 5 Linux 网络编程基础 API
  • 家教老师预约平台小程序系统开发方案
  • 数据结构-顺序表及其应用
  • 【pytorch练习】使用pytorch神经网络架构拟合余弦曲线
  • 电商项目-基于ElasticSearch实现商品搜索功能(一)
  • 2025-01-04 Unity插件 YodaSheet1 —— 插件介绍
  • 【深度学习入门_基础篇】线性代数本质
  • 进军AI大模型-Langchain程序部署
  • DS复习提纲模版
  • asp.net core 发布到iis后,一直500.19,IIS设置没问题,安装了sdk,文件夹权限都有,还是报错
  • RestClient操作Elasticsearch
  • 【Java】集合中的List【主线学习笔记】
  • 蓝色简洁引导页网站源码
  • 我们公司只有3个人,一个前端,一个后端