• 云盘项目——FastDFS


    在学习云盘项目总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

    12-云盘项目- 01天  FastDFS

    目录:
    一、课程安排
    二、项目
    1、项目整体架构
    2、web服务器
    3、分布式文件系统
    4、数据库和文件系统
    5、fastDFS三个角色和它们之间的关系
    6、fastDFS集群(了解)
    7、fastDFS安装
    8、追踪器配置文件修改
    9、存储节点配置文件
    10、客户端配置文件配置和fastDFS启动+测试
    11、fastDFS文件的上传和下载流程
    12、解决动态库找不到的问题
    13、fastDFS上传操作源码分析
    14、使用进程的方式实现文件的上传操作
    15、log日志文件的使用

    一、课程安排

    第01天(FastDFS):
        FastDFS概述
        安装和配置
        客户端编程
    第02天(redis、redis和mysql的交互):
        redis的安装和配置
        redis的数据类型
        redis客户端编程
        redis和mysql的交互
    第03天(Nginx、QListWidget和QJsonDocument的使用):
        Nginx环境搭建和配置
        Nginx反向代理
        Nginx负载均衡
        QListWidget的使用
        QJsonDocument的使用
    第04天(HTTP协议、FastCGI、QNetworkAccessManager的使用):
        FastCGI介绍
        FastCGI编程
        Nginx中配置FastCGI模块
        QNetworkAccessManager的使用
    第05天(Qt整体界面搭建和基本功能实现)
    第06-10天
        内部功能局部实现

    二、项目

    1、项目整体架构

    》系统架构图:

    1)通过浏览器/桌面客户端访问服务器
    ○ C/S
    ○ B/S
    2)反向代理服务器
    ○ 多台web服务器-集群
    ○ 给web服务器分配资源
    3)高并发
    ○ 多台web服务器
    4)nginx服务器+fastcgi
    ○ nginx处理静态请求
    ○ 动态需要使用FASTCGI处理
    5)数据库
    ○ mysql
    ○ redis
    6)分布式的文件系统- fastDFS
    ○ 上传和下载文件

    2、web服务器

    1)什么是服务器?
    ○ 硬件:一台配置比较高的电脑
    ○ 软件:在电脑上安装服务器软件

    2)常见的web服务器
    ○ tomcat服务器
        apache组织产品, 开源的免费服务器
    ○ weblogic服务器
        bea公司, 收费的服务器
        不交费, 访问量受限制
    ○ IIS服务器
        Internet Information Server
        微软公司主推的服务器
    ○ nginx
        小巧且高效的HTTP服务器
        也可以做一个高效的负载均衡反向代理

    3、分布式文件系统

    分布式文件系统
    1)文件系统 - 存储数据
        fat32, ntfs, ext3, ext4

    2)分布式
    ○ 一般文件系统


    ○ 分布式的文件系统
        文件系统的全部, 不在同一台主机上,在很多台主机上, 多个分散的文件系统组合在一起,形成了一个完整的文件系统。

        分布式的文件系统基本结构:

    4、数据库和文件系统

    5、fastDFS三个角色和它们之间的关系

    6、fastDFS集群(了解)

    7、fastDFS安装

    安装如下:

    8、追踪器配置文件修改

    修改配置文件:

    在这一个终端,修改配置(vi tracker.conf),

    打开另一个终端查看或创建文件

    9、存储节点配置文件

    修改配置(vi storage.conf):

    还需要修改port(看是否被占用)、base_path(/home/robin/fastDFS/storage)、store_path_count及对应的store_path0(依次输入路径,如:只用了一个,为/home/robin/fastDFS/storage)、tracker_server(tracker服务器的IP+端口)

    10、客户端配置文件配置和fastDFS启动+测试

    修改配置(vi client.conf):

    》fastDFS启动:

    (1)先启动tracker.conf

    (2)启动storage.conf

    (3)使用fdfs_monitor检测环境:

    注意:主要查看storage 1的状态是否是ACTIVE

    》fastDFS测试:

    (1)上传一个文件:

    (2)打开另一个终端,在(~/fastDFS/storage/data)查看:

    (3)在(~/fastDFS/storage/data/00/00/wkhs_vlqxxx6176431)查看,经过某些算法转换后存储了。M00为映射目录。

    (4)下载该文件,查看:

    11、fastDFS文件的上传和下载流程

    12、解决动态库找不到的问题

    13、fastDFS上传操作源码分析

    fastDFS api函数:(可参考fdfs_upload_file.c)

    14、使用进程的方式实现文件的上传操作

    15、log日志文件的使用

    >fdfs_api.h

    #ifndef _FDFS_API_H
    #define _FDFS_API_H
    int fdfs_upload_file(const char* conf_file, const char* myfile, char* file_id);
    #endif
    fdfs_api.h

    >fdfs_api.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <string.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include "fdfs_client.h"
    #include "logger.h"
    #include "make_log.h"
    
    int fdfs_upload_file(const char* conf_file, const char* myfile, char* file_id)
    {
        char group_name[FDFS_GROUP_NAME_MAX_LEN + 1];
        ConnectionInfo *pTrackerServer;
        int result;
        int store_path_index;
        ConnectionInfo storageServer;
        
        // 通过客户端配置文件初始化一些数据
        if ((result=fdfs_client_init(conf_file)) != 0)
        {
            LOG("111", "222", "fdfs_client_init error - %d", -1);
            return result;
        }
    
        // 通过从配置文件中读出的数据, 连接追踪器tracker
        // 通过得到的地址可以访问追踪器
        pTrackerServer = tracker_get_connection();
        if (pTrackerServer == NULL)
        {
            fdfs_client_destroy();
            return errno != 0 ? errno : ECONNREFUSED;
        }
    
        *group_name = '';
    
        // 通过tracker得到存储节点信息
        if ((result=tracker_query_storage_store(pTrackerServer, 
                        &storageServer, group_name, &store_path_index)) != 0)
        {
            fdfs_client_destroy();
            fprintf(stderr, "tracker_query_storage fail, " 
                "error no: %d, error info: %s
    ", 
                result, STRERROR(result));
            return result;
        }
    
        // 文件上传
        result = storage_upload_by_filename1(pTrackerServer, 
                &storageServer, store_path_index, 
                myfile, NULL, 
                NULL, 0, group_name, file_id);
        if (result == 0)
        {
            LOG("11", "222", "fileID: %s", file_id);
        }
        else
        {
            fprintf(stderr, "upload file fail, " 
                "error no: %d, error info: %s
    ", 
                result, STRERROR(result));
        }
    
        tracker_disconnect_server_ex(pTrackerServer, true);
        fdfs_client_destroy();
    
        return result;
    }
    fdfs_api.c

    >main.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include "fdfs_api.h"
    
    
    int main(int argc, char* argv[])
    {
        char fileid[1024] = {0};
        fdfs_upload_file("/etc/fdfs/client.conf", argv[1], fileid);
        printf("fileID = %s
    ", fileid);
    }

    >make_log.c

    #include<stdio.h>
    #include<stdarg.h>
    #include<string.h>
    #include<fcntl.h>
    #include<unistd.h>
    #include<time.h>
    #include<sys/stat.h>
    
    #include"make_log.h"
    #include<pthread.h>
    
    pthread_mutex_t ca_log_lock=PTHREAD_MUTEX_INITIALIZER;
    
    //创建目录并写入内容
    int dumpmsg_to_file(char *module_name, char *proc_name, const char *filename,
                            int line, const char *funcname, char *fmt, ...)
    {
            char mesg[4096]={0};
            char buf[4096]={0};
            char filepath[1024] = {0};
            time_t t=0;
            struct tm * now=NULL;                                                                                     
            va_list ap;                                                                                               
            //struct file_path *path;
            //path = (struct file_path*)paths;
            time(&t);                                                                                                 
            now = localtime(&t);                                       
            va_start(ap, fmt);                                                                               
            vsprintf(mesg, fmt, ap);                                                                       
            va_end(ap);                        
    
            snprintf(buf, 4096, "===%04d%02d%02d-%02d%02d%02d,%s[%d]=== %s
    ",
                                    now -> tm_year + 1900, now -> tm_mon + 1,                                         
                                    now -> tm_mday, now -> tm_hour, now -> tm_min, now -> tm_sec,
                                    funcname, line, mesg);                                     
            make_path(filepath, module_name, proc_name);
            
            pthread_mutex_lock(&ca_log_lock);
            out_put_file(filepath, buf);     
            pthread_mutex_unlock(&ca_log_lock);
    
            return 0;     
    }
    
    //写入内容
    int out_put_file(char *path, char *buf)
    {
        int fd;                                                                                                   
        fd = open(path, O_RDWR | O_CREAT | O_APPEND, 0777);
    
        if(write(fd, buf, strlen(buf)) != (int)strlen(buf)) {                                      
                fprintf(stderr, "write error!
    ");                           
                close(fd);                                                                                        
        } else {                                                                                                  
                //write(fd, "
    ", 1);
                close(fd);                                                                                        
        }               
    
        return 0;
    }
    //创建目录
    int make_path(char *path, char *module_name, char *proc_name)
    {
        time_t t;
        struct tm *now = NULL;
        char top_dir[1024] = {"."};
        char second_dir[1024] = {"./logs"};
        char third_dir[1024] = {0};
        char y_dir[1024] = {0};
        char m_dir[1024] = {0};
        char d_dir[1024] = {0}; 
        time(&t);
            now = localtime(&t);
        snprintf(path, 1024, "./logs/%s/%04d/%02d/%s-%02d.log", module_name, now -> tm_year + 1900, now -> tm_mon + 1, proc_name, now -> tm_mday);
        
        sprintf(third_dir, "%s/%s", second_dir, module_name);
        sprintf(y_dir, "%s/%04d/", third_dir, now -> tm_year + 1900);
        sprintf(m_dir, "%s/%02d/", y_dir, now -> tm_mon + 1);
        sprintf(d_dir,"%s/%02d/", m_dir, now -> tm_mday);
        
        if(access(top_dir, 0) == -1) {
            if(mkdir(top_dir, 0777) == -1) {
                fprintf(stderr, "create %s failed!
    ", top_dir);    
            } else if(mkdir(second_dir, 0777) == -1) {
                fprintf(stderr, "%s:create %s failed!
    ", top_dir, second_dir);
            } else if(mkdir(third_dir, 0777) == -1) {
                fprintf(stderr, "%s:create %s failed!
    ", top_dir, third_dir);
            } else if(mkdir(y_dir, 0777) == -1) {
                            fprintf(stderr, "%s:create %s failed!
    ", top_dir, y_dir);                                                     
                    } else if(mkdir(m_dir, 0777) == -1) {                                                             
                            fprintf(stderr, "%s:create %s failed!
    ", top_dir, m_dir);                                                     
                    }              
        } else if(access(second_dir, 0) == -1) {
            if(mkdir(second_dir, 0777) == -1) {
                fprintf(stderr, "create %s failed!
    ", second_dir);
            } else if(mkdir(third_dir, 0777) == -1) {
                fprintf(stderr, "%s:create %s failed!
    ", second_dir, third_dir);
                    } else if(mkdir(y_dir, 0777) == -1) {
                            fprintf(stderr, "%s:create %s failed!
    ", second_dir, y_dir);
                    } else if(mkdir(m_dir, 0777) == -1) {
                            fprintf(stderr, "%s:create %s failed!
    ", second_dir, m_dir);
                    }
        } else if(access(third_dir, 0) == -1) {
            if(mkdir(third_dir, 0777) == -1) {
                fprintf(stderr, "create %s failed!
    ", third_dir);
            } else if(mkdir(y_dir, 0777) == -1) {
                fprintf(stderr, "%s:create %s failed!
    ", third_dir, y_dir);
            } else if(mkdir(m_dir, 0777) == -1) {
                fprintf(stderr, "%s:create %s failed!
    ", third_dir, m_dir);
            } 
        } else if (access(y_dir, 0) == -1) {
            if(mkdir(y_dir, 0777) == -1) {
                fprintf(stderr, "create %s failed!
    ", y_dir);
            } else if(mkdir(m_dir, 0777) == -1) {
                            fprintf(stderr, "%s:create %s failed!
    ", y_dir, m_dir);
                    } 
    
        } else if (access(m_dir, 0) == -1) {
                    if(mkdir(m_dir, 0777)) {
                fprintf(stderr, "create %s failed!
    ", m_dir);
            } 
            }
        //printf("path:%s
    ", path);
        return 0;
    }
    make_log.c

    >make_log.h

    #ifndef  _MAKE_LOG_H_
    #define  _MAKE_LOG_H
    #include "pthread.h"
    
    int out_put_file(char *path, char *buf);
    int make_path(char *path, char *module_name, char *proc_name);
    int dumpmsg_to_file(char *module_name, char *proc_name, const char *filename,
                            int line, const char *funcname, char *fmt, ...);
    #ifndef _LOG
    #define LOG(module_name, proc_name, x...) 
            do{ 
            dumpmsg_to_file(module_name, proc_name, __FILE__, __LINE__, __FUNCTION__, ##x);
        }while(0)
    #else
    #define LOG(module_name, proc_name, x...)
    #endif
    
    extern pthread_mutex_t ca_log_lock;
    
    #endif
    make_log.h

    》编译测试:

    报错1:找不到fatal error:xxx.h,如fdfs_client.h

    报错2:reference tp 'fdfs_client_destroy_ex'

    >gcc fdfs_api.c main.c -I /usr/include/fastdfs/ -I /usr/include/fastcommon -lfdfsclient -o app

    上传一个文件测试:

    >./app make_log.h

    在fdfs_api.c增加头文件#include "make_log.h",然后把printf改成LOG函数(LOG(module_name, proc_name, x...)),再重新编译

    >gcc fdfs_api.c main.c make_log.c -I /usr/include/fastdfs/ -I /usr/include/fastcommon -lfdfsclient -o app

    上传一个文件测试:

    >./app main.c

    查看log:

    在学习云盘项目总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。

  • 相关阅读:
    第八章 1 元组简介
    第七章 5 字典生成式
    第七章 4 字典的视图操作、字典的遍历、字典的特点
    第七章 3 字典的常用操作(增删改查)
    第七章 2 字典的创建以及字典元素的获取
    第七章 1 字典介绍
    Java 中 Executors.newSingleThreadExecutor() 与Executors.newFixedThreadPool(1)有什么区别
    Java 使用线程池执行若干任务
    使用Jacoco获取 Java 程序的代码执行覆盖率
    基于 Golang 完整获取百度地图POI数据的方案
  • 原文地址:https://www.cnblogs.com/Alliswell-WP/p/CPlusPlus_CloudDisk_Project01.html
Copyright © 2020-2023  润新知