一。介绍fastdfs及原理
FastDFS是一款轻量级的开源分布式文件系统,它用纯C语言实现,支持Linux、FreeBSD、AIX等UNIX系统。只能通过 专有API对文件进行存取访问,不支持POSIX接口方式,不能mount使用.
原理介绍:
服务分为两大部件Tracker server和Storage server :Tracker server负责调度 计算最适合的存储服务器 ,Storage server负责存储数组 Storage server被分为多个组 ,不同的文件上传分发到不同的组中,同一组之间可以形成高可用的主从备份,同一组之间的服务器之间是互为拷贝,数据完全相同
fastdfs 安装
查询:docker search fastdfs
下载:docker pull season/fastdfs
本机方式启动注册中心tracker:docker run -itd --name trakcer -v ~/tracker_data:
/fastdfs/tracker/data --net=host season/fastdfs tracker
默认启动22122端口
禁用防火墙:vi /etc/sysconfig/selinux
重启虚拟机:reboot
防火墙禁用方法
启动仓库storage:docker run -itd --name storage -v ~/storage_data:/fastdfs/storage/data -v ~/store_path:/fastdfs/store_path --net=host -e TRACKER_SERVER:192.168.1.2:22122 season/fastdfs storage
进入容器
进入容器docker exec -it storage bash
查看配置:more storage.conf
复制出来,修改配置再拷贝回去:docker cp storage.conf:/fdfs_conf ~/
拷贝回去:docker cp ./storage.conf storage:/fdfs_conf/
因为docker是精简版的系统
将ip修改为Linux系统Ip;
重启storage:docker stop storage → docker start storage
再次进入storage容器: docker exec -it storage bash
确认配置是否修改成功
fdfs_monitor fdfs_conf/storage.conf
下图箭头为组名,默认group1,依次往上加,有组号说明tracker已启动
》》测试文件上传
查看/usr/bin下的所有fdfs工具
[root@bogon fdfs]# ls /usr/bin | grep fdfs
fdfs_appender_test
fdfs_appender_test1
fdfs_append_file
fdfs_crc32
fdfs_delete_file
fdfs_download_file
fdfs_file_info
fdfs_monitor
fdfs_storaged
fdfs_test
fdfs_test1
fdfs_trackerd
fdfs_upload_appender
fdfs_upload_file //上传文件
启动客户端
docker run -itd --name fdfs_sh --net=host season/fastdfs sh
创建a.txt文件同时赋值: echo Hello>a.txt
root@localhost:/# cd fdfs_conf
root@localhost:/fdfs_conf# fdfs_upload_file storage.conf /a.txt
group1/M00/00/00/wKiuglwGoJWARxYvAAAACZLaVGU072.txt //上传成功 返回的地址
//组名/地址/保证安全替换后的名字.后缀名
-v 映射路径
下载文件到本地:(fdfs_download_file [local_filename])
[root@bogon 00]# fdfs_download_file /etc/fdfs/client.conf group1/M00/00/00/wKg6klmyEG-AWCZjAAAADZDfcRo628.txt ~/bb.txt
[root@bogon 00]# ll ~
total 168836
-rw-------. 1 root root 2913 Apr 5 2016 anaconda-ks.cfg
-rw-r--r-- 1 root root 13 Sep 7 20:35 a.txt
-rw-r--r-- 1 root root 13 Sep 7 20:46 bb.tx
删除文件(fdfs_delete_file
[root@bogon 00]# fdfs_delete_file /etc/fdfs/client.conf group1/M00/00/00/wKg6klmyEG-AWCZjAAAADZDfcRo628.txt
#删除了该文件 还可以查看到它的信息
[root@bogon 00]# fdfs_file_info /etc/fdfs/client.conf group1/M00/00/00/wKg6klmyEG-AWCZjAAAADZDfcRo628.txt
source storage id: 0
source ip address: 192.168.58.146
file create timestamp: 2017-09-07 20:37:19
file size: 13
file crc32: 2430562586 (0x90DF711A)
#再次尝试删除 发现报错文件不存在
[root@bogon 00]# fdfs_delete_file /etc/fdfs/client.conf group1/M00/00/00/wKg6klmyEG-AWCZjAAAADZDfcRo628.txt
[2017-09-07 20:48:23] ERROR - file: tracker_proto.c, line: 48, server: 192.168.58.146:23000, response status 2 != 0
delete file fail, error no: 2, error info: No such file or directory
上传下载代码:
pom.xml文件:
cn
sn
https://oss.sonatype.org/content/repositories/releases/
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-jpa
com.luhuiguo
fastdfs-spring-boot-starter
0.2.0
mysql
mysql-connector-java
controller层:
@RestController
public class UploadController {
@Autowired
private FastFileStorageClient storageClient;
@Autowired
JdbcTemplate jdbcTemplate;
/**
*
* @param myFile 从浏览器提交过来
* @return
*/
@PostMapping("/fupload")
public String uploud(@RequestParam("myFile") MultipartFile myFile) throws IOException {
String extName = FilenameUtils.getExtension(myFile.getOriginalFilename());
StorePath sp=storageClient.uploadFile("group1",myFile.getInputStream(),myFile.getSize(),extName);
String sql ="insert into myfile(filename,groupname,filepath) values(?,?,?)";
jdbcTemplate.update(sql,myFile.getOriginalFilename(),sp.getGroup(),sp.getPath());
return sp.getFullPath();
}
@GetMapping("/fdownload/{id}")
public void download(@PathVariable String id , HttpServletResponse response) throws IOException {
List list = jdbcTemplate.query("select * from myfile where fileid ="+id,new ColumnMapRowMapper());
Map map=(Map)list.get(0);
//中文文件名要转码
String fileName = URLEncoder.encode(map.get("filename").toString(),"UTF-8");
String groupName= map.get("groupName").toString();
String pathName = map.get("filePath").toString();
//告诉浏览器下载的文件名
response.setHeader("Content-Disposition","attachment;filename="+ fileName+"");
//将文件内容输出到浏览器
byte[] bytes = storageClient.downloadFile(groupName, pathName);
response.getOutputStream().write(bytes);
}
}
html页面:
上传:
Title
下载:
Title
下载
配置文件application.yml:
#window端口:
server:
port: 8899
fdfs:
#连接超时时间(毫秒):
connect-timeout: 10000
#响应超时时间(毫秒):
so-timeout: 3000
#Linux系统Docker地址:
tracker-list:
- 192.168.85.128:22122
spring:
datasource:
#连接数据库:
url: jdbc:mysql://localhost/factory
password: ps123456
driver-class-name: com.mysql.jdbc.Driver
username: root
http:
# 设置下载文件大小,单位byte
multipart:
max-file-size: 10485760
返回数组 返回两个参数 第一个是存储的组名 第二是 文件的路径