Linux下搭建FastDFS单机版以及整合到SpringBoot中

一、环境说明

CentOS7;防火墙关闭;虚拟机地址:192.168.0.40;

所有的文件我都放在我虚拟机的/home/cesec/EMQ/fastdfs下了,可以自定义目录,到时候下面的替换成自定义的目录即可;

因为之前该虚拟机上搭建了其他的东西,因此这次就指定别名了,直接通过ip和端口访问;

二、单机版搭建

1、下载安装 libfastcommon

1.1、下载libfastcommon

wget https://github.com/happyfish100/libfastcommon/archive/V1.0.7.tar.gz

1.2、解压进入文件夹

tar -zxvf V1.0.7.tar.gz

cd libfastcommon-1.0.7

1.3、编译、安装

./make.sh

./make.sh install

1.4、libfastcommon.so 安装到了/usr/lib64/libfastcommon.so,但是FastDFS主程序设置的lib目录是/usr/local/lib,所以需要创建软链接

ln -s /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so
ln -s /usr/lib64/libfastcommon.so /usr/lib/libfastcommon.so
ln -s /usr/lib64/libfdfsclient.so /usr/local/lib/libfdfsclient.so
ln -s /usr/lib64/libfdfsclient.so /usr/lib/libfdfsclient.so 

2、下载安装FastFDS

2.1、下载FastFDS

wget https://github.com/happyfish100/fastdfs/archive/V5.05.tar.gz

2.2、解压并进入文件夹

tar -zxvf V5.05.tar.gz
cd fastdfs-5.05

2.3、编译、安装

./make.sh
./make.sh install

2.4、FastDFS 服务脚本设置的 bin 目录是 /usr/local/bin, 但实际命令安装在 /usr/bin/ 下,建立 /usr/bin 到 /usr/local/bin 的软链接。

ln -s /usr/bin/fdfs_trackerd   /usr/local/bin
ln -s /usr/bin/fdfs_storaged   /usr/local/bin
ln -s /usr/bin/stop.sh         /usr/local/bin
ln -s /usr/bin/restart.sh      /usr/local/bin

3、配置FastDFS跟踪器(Tracker)

3.1、 进入 /etc/fdfs,复制 FastDFS 跟踪器样例配置文件 tracker.conf.sample,并重命名为 tracker.conf

cd /etc/fdfs
cp tracker.conf.sample tracker.conf

3.2、编辑tracker.conf ,标红的需要修改下,其它的默认即可

vim tracker.conf

 Linux下搭建FastDFS单机版以及整合到SpringBoot中_第1张图片

 http.server_port很容易冲突,最好修改了,这个在文件的最下面

3.3、创建tracker基础数据目录,即base_path对应的目录

mkdir -p /home/cesec/EMQ/fastdfs/tracker

3.4、防火墙如果开着的话进行该步骤,否则跳过,防火墙中打开跟踪端口(默认的22122)

vim /etc/sysconfig/iptables

添加如下端口行:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22122 -j ACCEPT

重启防火墙:
service iptables restart

 3.5、启动Tracker,初次成功启动,会在/home/cesec/EMQ/fastdfs/tracker/ (配置的base_path)下创建 data、logs 两个目录。

service fdfs_trackerd start

查看 FastDFS Tracker 是否已成功启动 ,22122端口正在被监听,则算是Tracker服务安装成功。

 关闭Tracker命令:

service fdfs_trackerd stop

 设置Tracker开机启动:

chkconfig fdfs_trackerd on

关于tracker server 目录及文件结构 :

${base_path}
  |__data
  |   |__storage_groups.dat:存储分组信息
  |   |__storage_servers.dat:存储服务器列表
  |__logs
  |   |__trackerd.log: tracker server 日志文件 

4、配置 FastDFS 存储 (Storage)

4.1、进入 /etc/fdfs 目录,复制 FastDFS 存储器样例配置文件 storage.conf.sample,并重命名为 storage.conf

cd /etc/fdfs
cp storage.conf.sample storage.conf

4.2、编辑storage.conf,标红的需要修改,其它的默认即可。

vim storage.conf

 Linux下搭建FastDFS单机版以及整合到SpringBoot中_第2张图片

4.3、创建Storage基础数据目录,对应base_path目录

mkdir -p /home/cesec/EMQ/fastdfs/storage

#这是配置的store_path0路径
mkdir -p /home/cesec/EMQ/fastdfs/file

4.4、 防火墙如果开着的话进行该步骤,否则跳过,防火墙中打开跟踪端口(默认的23000)

vim /etc/sysconfig/iptables

添加如下端口行:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 23000 -j ACCEPT

重启防火墙:
service iptables restart

 4.5、启动 Storage,启动Storage前确保Tracker是启动的。初次启动成功,会在 /ljzsg/fastdfs/storage 目录下创建 data、 logs 两个目录。

service fdfs_storaged start

查看 Storage 是否成功启动,23000 端口正在被监听,就算 Storage 启动成功。

查看Storage和Tracker是否在通信:

/usr/bin/fdfs_monitor /etc/fdfs/storage.conf

Linux下搭建FastDFS单机版以及整合到SpringBoot中_第3张图片 

关闭Storage命令:

service fdfs_storaged stop

设置 Storage 开机启动:

chkconfig fdfs_storaged on

 4.6、Storage 目录,同 Tracker,Storage 启动成功后,在base_path 下创建了data、logs目录,记录着 Storage Server 的信息。

在 store_path0 目录下,创建了N*N个子目录:

 5、文件上传测试

5.1、修改 Tracker 服务器中的客户端配置文件 

cd /etc/fdfs
cp client.conf.sample client.conf
vim client.conf

修改如下配置即可,其它默认

Linux下搭建FastDFS单机版以及整合到SpringBoot中_第4张图片

 5.2、上传测试,在linux内部执行如下命令上传 1.jpg 图片

/usr/bin/fdfs_upload_file /etc/fdfs/client.conf 1.jpg

上传成功后返回文件ID号:group1/M00/00/00/wKgAKF159D6AaOJ1AALKF34wl18657.jpg

 

 返回的文件ID由group、存储目录、两级子目录、fileid、文件后缀名(由客户端指定,主要用于区分文件类型)拼接而成。

Linux下搭建FastDFS单机版以及整合到SpringBoot中_第5张图片

三、安装Nginx

上面将文件上传成功了,但我们无法下载。因此安装Nginx作为服务器以支持Http方式访问文件。Nginx只需要安装到StorageServer所在的服务器即可,用于访问文件。我这里由于是单机,TrackerServer和StorageServer在一台服务器上。

1、安装nginx所需环境

gcc 安装

yum install gcc-c++

PCRE pcre-devel 安装

yum install -y pcre pcre-devel

zlib 安装

yum install -y zlib zlib-devel

OpenSSL 安装

yum install -y openssl openssl-devel

2、安装Nginx

2.1、下载nginx

wget -c https://nginx.org/download/nginx-1.12.1.tar.gz

2.2、解压

tar -zxvf nginx-1.12.1.tar.gz
cd nginx-1.12.1

 2.3、使用默认配置

./configure

 2.4、编译、安装,修改端口号

make
make install

Nginx默认的是80端口,很容易冲突,最好修改一下,vim /usr/local/nginx/conf/nginx.conf

2.5、启动nginx

cd /usr/local/nginx/sbin/
./nginx 

其它命令
./nginx -s stop
./nginx -s quit
./nginx -s reload

 2.6、设置开机启动

vim /etc/rc.local

添加一行:
/usr/local/nginx/sbin/nginx

设置执行权限
chmod 755 rc.local

2.7、查看nginx的版本及模块

/usr/local/nginx/sbin/nginx -V

 

2.8、防火墙如果开着的话进行该步骤,否则跳过,防火墙中打开跟踪端口(默认的80,但是我修改为了6767)

vim /etc/sysconfig/iptables

添加如下端口行:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 6767 -j ACCEPT

重启防火墙:
service iptables restart

3、访问文件

1、修改nginx.conf

vim /usr/local/nginx/conf/nginx.conf

添加如下行,将 /group1/M00 映射到 /home/cesec/EMQ/fastdfs/file/data
location /group1/M00 {
    alias /home/cesec/EMQ/fastdfs/file/data;
}

# 重启nginx
/usr/local/nginx/sbin/nginx -s reload

 Linux下搭建FastDFS单机版以及整合到SpringBoot中_第6张图片

2、在浏览器访问之前上传的图片、成功,

http://192.168.0.40:6767/group1/M00/00/00/wKgAKF159D6AaOJ1AALKF34wl18657.jpg

Linux下搭建FastDFS单机版以及整合到SpringBoot中_第7张图片

四、整合到SpringBoot中

1、pom.xml加入依赖


        
            com.github.tobato
            fastdfs-client
            1.26.5
            
                
                    ch.qos.logback
                    logback-classic
                
            
        

2、application.yml加入参数

# FastDFS
# ===================================================================
# 分布式文件系统FDFS配置
# ===================================================================
fdfs:
  so-timeout: 1501
  connect-timeout: 601
  thumb-image:             #缩略图生成参数
    width: 150
    height: 150
  web-server-url: http://192.168.0.40:6767/
  tracker-list: 192.168.0.40:22122

 3、添加FastDFS工具类

@Component
public class FastDFSClient {
    private final Logger logger = LoggerFactory.getLogger(FastDFSClient.class);

    @Autowired
    private FastFileStorageClient storageClient;

    @Autowired
    private FdfsWebServer fdfsWebServer;

    /**
     * 上传文件
     * @param file 文件对象
     * @return 文件访问地址
     * @throws IOException
     */
    public String uploadFile(MultipartFile file) throws IOException {
        StorePath storePath = storageClient.uploadFile(file.getInputStream(),file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()),null);
        return getResAccessUrl(storePath);
    }

    /**
     * 上传文件
     * @param file 文件对象
     * @return 文件访问地址
     * @throws IOException
     */
    public String uploadFile(File file) throws IOException {
        FileInputStream inputStream = new FileInputStream (file);
        StorePath storePath = storageClient.uploadFile(inputStream,file.length(), FilenameUtils.getExtension(file.getName()),null);
        return getResAccessUrl(storePath);
    }

    /**
     * 将一段字符串生成一个文件上传
     * @param content 文件内容
     * @param fileExtension
     * @return
     */
    public String uploadFile(String content, String fileExtension) {
        byte[] buff = content.getBytes(Charset.forName("UTF-8"));
        ByteArrayInputStream stream = new ByteArrayInputStream(buff);
        StorePath storePath = storageClient.uploadFile(stream,buff.length, fileExtension,null);
        return getResAccessUrl(storePath);
    }

    // 封装图片完整URL地址
    private String getResAccessUrl(StorePath storePath) {
        String fileUrl = fdfsWebServer.getWebServerUrl() + storePath.getFullPath();
        return fileUrl;
    }

    /**
     * 下载文件,返回字节数组
     * @param fileUrl 文件url
     * @return
     */
    public byte[] downloadByte(String fileUrl) {
        ConcurrentHashMap pathMap = getPath(fileUrl);
        String groupName = pathMap.get("groupName");
        String filePath = pathMap.get("filePath");
        byte[] bytes = storageClient.downloadFile(groupName, filePath, new DownloadByteArray());
        return bytes;
    }

    /**
     * 下载文件,返回InputStream
     * @param fileUrl 文件url
     * @return
     */
    public InputStream downloadInputStream(String fileUrl) {
        ConcurrentHashMap pathMap = getPath(fileUrl);
        String groupName = pathMap.get("groupName");
        String filePath = pathMap.get("filePath");
        InputStream ins =  storageClient.downloadFile(groupName, filePath, new DownloadCallback(){
            @Override
            public InputStream recv(InputStream ins) throws IOException {
                // 将此ins返回给上面的ins
                return ins;
            }}) ;
        return ins ;

    }

    /**
     * 下载文件,返回文件
     * @param fileUrl 文件url
     * @return
     */
    public void downloadFile(String fileUrl, HttpServletRequest request, HttpServletResponse response){
        try {
            ConcurrentHashMap pathMap = getPath(fileUrl);
            String groupName = pathMap.get("groupName");
            String filePath = pathMap.get("filePath");
            String fileName = pathMap.get("fileName");
            InputStream input =  storageClient.downloadFile(groupName, filePath, new DownloadCallback(){
                @Override
                public InputStream recv(InputStream input) throws IOException {
                    // 将此input返回给上面的input
                    return input;
                }}) ;

            //根据文件名获取 MIME 类型
            System.out.println("fileName :" + fileName); // wKgAKF15nkOAdYczAACrr9cLDU4592.jpg
            String contentType = request.getServletContext().getMimeType(fileName);
            String contentDisposition = "attachment;filename=" + fileName;

            // 设置头
            response.setHeader("Content-Type",contentType);
            response.setHeader("Content-Disposition",contentDisposition);

            // 获取绑定了客户端的流
            ServletOutputStream output = response.getOutputStream();

            // 把输入流中的数据写入到输出流中

            IOUtils.copy(input,output);
            input.close();
        } catch (IOException e) {
            e.printStackTrace();

        }
    }

    /**
     * 删除文件
     * @param fileUrl 文件访问地址
     * @return
     */
    public void deleteFile(String fileUrl) {
        if (StringUtils.isEmpty(fileUrl)) {
            return;
        }
        try {
            StorePath storePath = StorePath.parseFromUrl(fileUrl);
            storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
        } catch (FdfsUnsupportStorePathException e) {
            logger.warn(e.getMessage());
        }
    }

    /**
     * @Description: 将传过来的url切割成需要的url
     * @Author: yelei
     * @Date: 2019/9/12
     */
    public ConcurrentHashMap getPath(String fileUrl){
        ConcurrentHashMap pathMap = new ConcurrentHashMap<>();
        String groupName = fileUrl.substring(fileUrl.indexOf("g"),fileUrl.indexOf("M") - 1);
        String filePath = fileUrl.substring(fileUrl.indexOf("M"));
        String fileName = fileUrl.substring(fileUrl.lastIndexOf("/")+1);
        pathMap.put("groupName",groupName);
        pathMap.put("filePath",filePath);
        pathMap.put("fileName",fileName);
        return pathMap;
    }
}

4、测试

@Controller
@RequestMapping("fastdfs/")
public class TestController {

    @Autowired
    private FastDFSClient fastDFSClient;

    @GetMapping()
    public void test(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //上传
        File file = new File("E:\\2.jpg");
        String url = fastDFSClient.uploadFile(file);
        System.out.println(url);
        //下载
        fastDFSClient.downloadFile("http://192.168.0.40:6767/group1/M00/00/00/wKgAKF15nkOAdYczAACrr9cLDU4592.jpg",request,response);
        //删除
        fastDFSClient.deleteFile("http://192.168.0.40:6767/group1/M00/00/00/wKgAKF15nkOAdYczAACrr9cLDU4592.jpg");

    }
}

 

你可能感兴趣的:(Java高级)