云盘项目——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.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 = '\0'; // 通过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\n", \ 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\n", \ result, STRERROR(result)); } tracker_disconnect_server_ex(pTrackerServer, true); fdfs_client_destroy(); return result; }
>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\n", 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\n", 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!\n"); close(fd); } else { //write(fd, "\n", 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!\n", top_dir); } else if(mkdir(second_dir, 0777) == -1) { fprintf(stderr, "%s:create %s failed!\n", top_dir, second_dir); } else if(mkdir(third_dir, 0777) == -1) { fprintf(stderr, "%s:create %s failed!\n", top_dir, third_dir); } else if(mkdir(y_dir, 0777) == -1) { fprintf(stderr, "%s:create %s failed!\n", top_dir, y_dir); } else if(mkdir(m_dir, 0777) == -1) { fprintf(stderr, "%s:create %s failed!\n", top_dir, m_dir); } } else if(access(second_dir, 0) == -1) { if(mkdir(second_dir, 0777) == -1) { fprintf(stderr, "create %s failed!\n", second_dir); } else if(mkdir(third_dir, 0777) == -1) { fprintf(stderr, "%s:create %s failed!\n", second_dir, third_dir); } else if(mkdir(y_dir, 0777) == -1) { fprintf(stderr, "%s:create %s failed!\n", second_dir, y_dir); } else if(mkdir(m_dir, 0777) == -1) { fprintf(stderr, "%s:create %s failed!\n", second_dir, m_dir); } } else if(access(third_dir, 0) == -1) { if(mkdir(third_dir, 0777) == -1) { fprintf(stderr, "create %s failed!\n", third_dir); } else if(mkdir(y_dir, 0777) == -1) { fprintf(stderr, "%s:create %s failed!\n", third_dir, y_dir); } else if(mkdir(m_dir, 0777) == -1) { fprintf(stderr, "%s:create %s failed!\n", third_dir, m_dir); } } else if (access(y_dir, 0) == -1) { if(mkdir(y_dir, 0777) == -1) { fprintf(stderr, "create %s failed!\n", y_dir); } else if(mkdir(m_dir, 0777) == -1) { fprintf(stderr, "%s:create %s failed!\n", y_dir, m_dir); } } else if (access(m_dir, 0) == -1) { if(mkdir(m_dir, 0777)) { fprintf(stderr, "create %s failed!\n", m_dir); } } //printf("path:%s\n", path); return 0; }
>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
》编译测试:
报错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,转载请注明出处。
posted on 2020-08-06 11:12 Alliswell_WP 阅读(715) 评论(0) 编辑 收藏 举报