安装fastDFS需要分别安装fastdfs-nginx-module,fastdfs,nginx,libfastcommon
网上有下载,注意版本的搭配
1、安装gcc(编译时需要)
yum install -y gcc gcc-c++
2、安装libevent (运行时需要
yum -y install libevent
3、安装创建目录上传文件
参考:
mkdir -p /fileservice/fast
cd /fileservice/fast
5、安装fastdfs
6、配置和启动tracker
7、配置和启动storage
切换目录到: /etc/fdfs/ 目录下;
修改storage.conf
vi storage.conf
base_path=/home/yuqing/fastdfs 改为:
base_path=/home/fastdfs/storage
store存放文件的位置(store_path)
store_path0=/home/yuqing/fastdfs 改为:
store_path0=/home/fastdfs/storage
如果有多个挂载磁盘则定义多个store_path,如下
store_path1=…
store_path2=…
配置tracker服务器:IP
tracker_server=192.168.59.128:22122
创建/home/fastdfs/storage 目录
mkdir -p /home/fastdfs/storage
启动storage, 运行命令如下:
service fdfs_storaged start
启动完成后进入 /home/fastdfs/storage/data 目录下,显示目录如下:
8、使用FastDFS自带工具测试
9、FastDFS 和nginx整合
在tracker上安装 nginx在每个tracker上安装nginx,的主要目的是做负载均衡及实现高可用。如果只有一台tracker可以不配置nginx。
一个tracker对应多个storage,通过nginx对storage负载均衡
在storage 上安装nginx
上传fastdfs-nginx-module-1.20.tar.gz 到Centos服务器上
解压fastdfs-nginx-module-1.20.tar.gz ;
tar -zxvf fastdfs-nginx-module-1.20.tar.gz
切换目录到: fastdfs-nginx-module-1.20/src 目录下
cd fastdfs-nginx-module-1.20/src4.修改config文件,将文件中的所有 /usr/local/ 路径改为 /usr/
修改之后
将fastdfs-nginx-module/src下的mod_fastdfs.conf拷贝至/etc/fdfs/下
cp mod_fastdfs.conf /etc/fdfs/
并修改 /etc/fdfs/mod_fastdfs.conf 的内容;
vi /etc/fdfs/mod_fastdfs.conf
类容如下:
tracker_server=192.168.59.128:22122
tracker_server=192.168.172.20:22122 #(多个tracker配置多行)
url_have_group_name=true #url中包含group名称
store_path0=/home/fdfs_storage #指定文件存储路径(上面配置的store路径)
3.进入之前解压的fastdfs目录下,把http.conf、mime.conf移动至/etc/fdfs
10、Nginx的安装
上传 nginx-1.15.2.tar.gz 到Centos服务器上;
解压 nginx-1.15.2.tar.gz
tar -zxvf nginx-1.15.2.tar.gz
进入nginx解压的目录下
cd nginx-1.15.2/
加入模块命令配置
./configure --prefix=/opt/nginx --sbin-path=/usr/bin/nginx --add-module=/fileservice/fast/fastdfs-nginx-module-1.20/src
编译并安装
make && make install
修改nginx配置
cd /opt/nginx/conf
启动nginx
cd /usr/bin/
./nginx #启动
11、在浏览器中访问上传到fastDFS的图片
因为Centos系统有防火墙,需要先关闭掉,才可以在浏览器中访问;
1、CentOS7.0默认使用的是firewall作为防火墙;若没有启用iptables 作为防火墙,则使用以下方式关闭防火墙:
systemctl stop firewalld.service #停止firewallsystemctl disable firewalld.service #禁止firewall开机启动
firewall-cmd --state #查看默认防火墙状态(关闭后显示notrunning,开启后显示running)
2、若已经启用iptables作为防火墙,则使用以下方式关闭:
service iptables stop #临时关闭防火墙
chkconfig iptables off #永久关闭防火墙
3、在谷歌浏览器中访问刚才上传的图片:
刚才上传的图片地址为:
http://192.168.59.128/group1/M00/00/00/wKg7gF5w8a6ASQ9bAAy9bu9NQiQ753.png
1、下载FastDFS 镜像
docker pull delron/fastdfs
2、查看下载好的镜像
docker images
3、然后使用docker镜像构建tracker容器(跟踪服务器,起到调度的作用),这里tracker服务将会自动映射到宿主机上
docker run -d --network=host --name tracker -v /home/fastdfsDoc/tracker:/var/fdfs delron/fastdfs tracker
4、使用docker镜像构建storage容器(存储服务器,提供容量和备份服务),这里storage容器需要依赖tracker服务,传入你的tracker服务的ip地址,端口默认是22122,ip地址也就是你宿主机的ip
docker run -d --network=host --name storage -e TRACKER_SERVER=192.168.59.128:22122 -v /home/fastdfsDoc/storage:/var/fdfs -e GROUP_NAME=group1 delron/fastdfs storage
5、配置nginx监听端口
a、启动nginx,这里nginx映射到宿主机上
docker run -it --name=myNginx -v /home/fastdfsDoc/nginx:/etc/nginx -p 80:80 nginx
6、上传测试
首先将一张照片lol.png放置在宿主机/home/fatsdfsDoc/storage目录下,然后我们进入storage容器里面,运行下面命令:
1、进入容器命令
docker exec -it 97fc6e9d7dbb /bin/bash
2、运行测试程序,读取/etc/fdfs/client.conf 文件,上传/home/fastdfsDoc/sotraeg目录下的lol.png文件
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf lol.png
1、创建项目导入pom依赖
<dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27.0.0</version>
</dependency>
<!-- spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.25.RELEASE</version>
</dependency>
2、创建fdfs_client.conf
# 连接超时时间
connect_timeout=30
# 网咯连接超时时间
network_timeout=60
# 在宿主机中的位置
base_path=/home/fastdfsDoc/storage
# 服务器IP 地址
tracker_server = 192.168.59.128:22122
log_level=info
use_connection_pool = false
connection_pool_max_idle_time = 3600
load_fdfs_parameters_from_tracker=false
use_storage_id = false
storage_ids_filename = storage_ids.conf
http.tracker_server_port=80
3、测试类进行文件上传
package com.hyf;
import org.csource.fastdfs.*;
import org.springframework.core.io.ClassPathResource;
import java.io.IOException;
/**
* Hello world!
*
*/
public class App
{
public static void main( String[] args ) throws Exception {
// 需要上传的本机文件地址
String uploadFilePath = "E:/images/stationmaster_img.png";
// 获取配置文件绝对路径
String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();
// 1、加载配置文件,配置文件中的类容就是tracker 服务的地址
ClientGlobal.init(filePath);
// 2、创建一个 TrackerClient 对象。直接 new 一个
TrackerClient trackerClient = new TrackerClient();
// 3、使用TrackerClient 对象创建连接,获得 Tracker 对象
TrackerServer trackerServer = trackerClient.getConnection();
// 4、创建一个 storageServer 的引用,值为 null
StorageServer storageServer = null;
// 5、创建一个StorageClient 对象,需要2个参数对象,StorageServer 的引用
StorageClient storageClient = new StorageClient(trackerServer, storageServer);
// 6、使用 StorageClinet 对象传送图片
String [] strings = storageClient.upload_file(uploadFilePath,"png",null);
// 7、返回数组。包含组名和图片的路径。
for (String string : strings) {
System.out.println(string);
}
System.out.println("上传完成");
}
}
1、创建springBoot 过程导入相关的 pom 依赖
<dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
2、配置yml文件
fastdfs:
connect_timeout_in_seconds: 100
network_timeout_in_seconds: 100
charset: UTF-8
tracker_services: 192.168.59.128:22122 # 如果需要骗子多个就用 , 隔开
3、创建UploadService
package com.hyf.fastdfsspringboot1.utils;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import org.csource.common.MyException;
import org.csource.fastdfs.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* @author xhy
* @site www.4399.com
* @company xxx公司
* @create 2020-03-18 23:57
*
* connect_timeout_in_seconds: 100
* network_timeout_in_seconds: 100
* charset: UTF-8
* tracker_services
*/
@Component
public class UploadService {
// IP 地址
@Value("${fastdfs.tracker_services}")
private String tracker_services;
@Value("${fastdfs.connect_timeout_in_seconds}")
private int connect_timeout_in_seconds;
@Value("${fastdfs.network_timeout_in_seconds}")
private int network_timeout_in_seconds;
@Value("${fastdfs.charset}")
private String charset;
public Map<String, Object> upload(MultipartFile multipartFile) {
if (multipartFile == null) {
throw new RuntimeException("文件不能为空");
}
// 上传到 fastDFS,返回 id
String fileId = this.fdfsUpload(multipartFile);
if (StringUtils.isEmpty(fileId)) {
System.out.println("上传失败");
throw new RuntimeException("上传失败");
}
Map<String, Object> map = new HashMap<>();
map.put("code", 200);
map.put("msg", "上传成功");
map.put("code", fileId); // 文件地址
return map;
}
/**
* 上传至 fastDFS
* @param multipartFile
*/
private String fdfsUpload(MultipartFile multipartFile) {
// 初始化环境
initFdfsConfig();
// 直接 new 一个 trackerClient
TrackerClient trackerClient = new TrackerClient();
try {
// 使用TrackerClient 创建连接对象Connection ,获得TrackerService 对象
TrackerServer trackerServer = trackerClient.getConnection();
// 获取到 StorageService 服务
StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
// 获取到 StorageClient
StorageClient1 storageClient1 = new StorageClient1(trackerServer, storageServer);
// 文件上传
//获得文件扩展名
String originalFilename = multipartFile.getOriginalFilename();
// 截取到该文件是以 .什么结尾
String substring = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
// 上传
String fileId = storageClient1.upload_appender_file1(multipartFile.getBytes(), substring, null);
return fileId;
} catch (Exception e) {
System.out.println();
return null;
}
}
/**
* 初始化 fastDFS 的环境
*/
public void initFdfsConfig() {
try {
ClientGlobal.initByTrackers(tracker_services);
ClientGlobal.setG_connect_timeout(connect_timeout_in_seconds);
ClientGlobal.setG_network_timeout(network_timeout_in_seconds);
ClientGlobal.setG_charset(charset);
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}
}
}
4、controller
package com.hyf.fastdfsspringboot1.controller;
import com.hyf.fastdfsspringboot1.utils.UploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.Map;
/**
* @author xhy
* @site www.4399.com
* @company xxx公司
* @create 2020-03-19 0:29
*/
@RestController
@RequestMapping("upload")
public class UploadController {
@Autowired
private UploadService uploadService;
/*
* 文件上传
* */
@RequestMapping("doUpload")
public Map<String,Object> doUpload(MultipartFile mf){
Map<String, Object> upload = uploadService.upload(mf);
return upload;
}
}
5、index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<h1>文件上传</h1>
<hr>
<form action="/upload/doUpload" method="post" enctype="multipart/form-data">
<input type="file" name="mf">
<input type="submit" value="上传">
</form>
</body>
</html>
1、创建springBoot过程导入相关pom依赖:
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.7</version>
</dependency>
2、yml
fdfs:
so-timeout: 2500 #读取时间
connect-timeout: 600 #连接超时时间
thumb-image: #缩略图
width: 100
height: 100
tracker-list: #tracker 服务配置地址
- 192.168.59.128:22122
upload:
base-url : http://192.168.59.128:8888/
allow-types:
- image/jpeg
- image/png
- image/bmp
- image/gif
3、自定义配置类,读取yml文件数据
package com.hyf.fastdfsspringboot2.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author xhy
* @site www.4399.com
* @company xxx公司
* @create 2020-03-19 21:10
*/
@ConfigurationProperties(prefix = "upload")
public class UploadProperties {
private String baseUrl; // 访问的IP地址
private List<String> allowTypes; //文件类型
public String getBaseUrl() {
return baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
public List<String> getAllowTypes() {
return allowTypes;
}
public void setAllowTypes(List<String> allowTypes) {
this.allowTypes = allowTypes;
}
}
4、文件上传工具类
package com.hyf.fastdfsspringboot2.utlis;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.hyf.fastdfsspringboot2.config.UploadProperties;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
/**
* @author xhy
* @site www.4399.com
* @company xxx公司
* @create 2020-03-19 22:00
*/
@Component
@EnableConfigurationProperties(UploadProperties.class)
public class UploadService {
private Log log= LogFactory.getLog(UploadService.class);
@Autowired
private FastFileStorageClient storageClient; // 封装好了文件上传的接口
@Autowired
private UploadProperties properties;
public String uploadImage(MultipartFile file){
// 判断文件类型是否匹配
String contentType = file.getContentType();
if(!properties.getAllowTypes().contains(contentType)){
throw new RuntimeException("文件类型不匹配");
}
// 校验文件类容
try {
BufferedImage image = ImageIO.read(file.getInputStream());
if(image == null && image.getWidth() == 0 && image.getHeight() == 0){
throw new RuntimeException("上传文件有问题");
}
} catch (IOException e) {
log.error("校验文件内容失败....{}", e);
throw new RuntimeException("校验文件内容失败"+e.getMessage());
}
try {
// 上传到 fastDFS
// 获取扩展名
String extension = StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
System.err.println("------------file.getOriginalFilename()----------"+file.getOriginalFilename());
// 上传
StorePath storePath = storageClient.uploadFile(file.getInputStream(),file.getSize(),extension,null);
System.err.println("------------file.getInputStream()----------"+file.getInputStream());
// 返回的路径
return properties.getBaseUrl()+storePath.getFullPath();
} catch (IOException e) {
log.error("【文件上传】上传文件失败!....{}", e);
throw new RuntimeException("【文件上传】上传文件失败!"+e.getMessage());
}
}
}
5、controller
package com.hyf.fastdfsspringboot2.controller;
import com.hyf.fastdfsspringboot2.utlis.UploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
import java.util.Map;
/**
* @author xhy
* @site www.4399.com
* @company xxx公司
* @create 2020-03-19 0:29
*/
@RestController
@RequestMapping("upload")
public class UploadController {
@Autowired
private UploadService uploadService;
/*
* 文件上传
* */
@RequestMapping("doUpload")
public Map<String,Object> doUpload(MultipartFile mf){
System.out.println("--------------mf___________"+mf.getOriginalFilename());
String filePath = uploadService.uploadImage(mf);
Map map = new HashMap();
map.put("path",filePath);
return map;
}
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<body>
<h1>文件上传</h1>
<hr>
<form action="/upload/doUpload" method="post" enctype="multipart/form-data">
<input type="file" name="mf">
<input type="submit" value="上传">
</form>
</body>
</html>
运行测试: