fastdfs安装、单机部署、java客户端连接

fastdfs安装步骤

具体查看github的安装步骤

1.安装编译环境

yum install git gcc gcc-c++ make automake autoconf libtool pcre pcre-devel zlib zlib-devel openssl-devel -y

2.创建目录

mkdir -p /fastdfs/tracker  #创建跟踪服务器数据目录
mkdir -p /fastdfs/storage  #创建存储服务器数据目录
 #切换到安装目录准备下载安装包
cd /usr/local/src 

3.安装libfatscommon

git clone https://github.com/happyfish100/libfastcommon.git --depth 1
cd libfastcommon/
./make.sh && ./make.sh install

4.安装FastDFS

git clone https://github.com/happyfish100/fastdfs.git --depth 1
cd fastdfs/
./make.sh && ./make.sh install
#配置文件准备
cp /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf
cp /etc/fdfs/storage.conf.sample /etc/fdfs/storage.conf
cp /etc/fdfs/client.conf.sample /etc/fdfs/client.conf #客户端文件,测试用
cp /usr/local/src/fastdfs/conf/http.conf /etc/fdfs/ #供nginx访问使用
cp /usr/local/src/fastdfs/conf/mime.types /etc/fdfs/ #供nginx访问使用

5.安装fastdfs-nginx-module

git clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1
cp /usr/local/src/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs

6.安装nginx

wget http://nginx.org/download/nginx-1.14.0.tar.gz
tar -zxvf nginx-1.14.0.tar.gz
cd nginx-1.14.0
#添加fastdfs-nginx-module模块
./configure --add-module=/usr/local/src/fastdfs-nginx-module/src/
make && make install

单机部署

tracker配置

vim /etc/fdfs/tracker.conf
#需要修改的内容如下
port=22122  # tracker服务器端口(默认22122,一般不修改)
base_path=/fastdfs/tracker  # 存储日志和数据的根目录
#保存后启动
/etc/init.d/fdfs_trackerd start #启动tracker服务
chkconfig fdfs_trackerd on #自启动tracker服务

storage配置

vim /etc/fdfs/storage.conf
#需要修改的内容如下
port=23000  # storage服务端口(默认23000,一般不修改)
base_path=/fastdfs/storage  # 数据和日志文件存储根目录
store_path0=/fastdfs/storage  # 第一个存储目录
tracker_server=192.168.0.xxx:22122  # tracker服务器IP和端口
http.server_port=8888  # http访问文件的端口(默认8888,看情况修改,和nginx中保持一致)
#保存后启动
/etc/init.d/fdfs_storaged start #启动storage服务
chkconfig fdfs_storaged on #自启动storage服务

client测试

vim /etc/fdfs/client.conf
#需要修改的内容如下
base_path=/fastdfs/tracker
tracker_server=192.168.1.xxx:22122    #tracker IP地址
#保存后测试,返回ID表示成功 eg:group1/M00/00/00/wKgAQ1pysxmAaqhAAA76tz-dVgg.tar.gz
fdfs_upload_file /etc/fdfs/client.conf /usr/local/src/nginx-1.12.2.tar.gz

配置nginx访问

vim /etc/fdfs/mod_fastdfs.conf
#需要修改的内容如下
tracker_server=192.168.0.xxx:22122
url_have_group_name=true
store_path0=/fastdfs/storage
#配置nginx.config
vi /usr/local/nginx/conf/nginx.conf
#添加如下配置
server {
    listen       8888;    ## 该端口为storage.conf中的http.server_port相同
    server_name  localhost;
    location ~/group[0-9]/ {
        ngx_fastdfs_module;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
    root   html;
    }
}
#测试下载,用外部浏览器访问刚才已传过的nginx安装包,引用返回的ID
http://192.168.0.xxx:8888/group1/M00/00/00/wKgAQ1pysxmAaqhAAA76tz-dVgg.tar.gz
#弹出下载单机部署全部跑通,否则首先检查防火墙,再检查其他配置。

fastdfs-client-java

github客户端源码

# 生成本地jar包,线上项目使用的话,可以传到你们自己的私有仓库
git clone https://github.com/happyfish100/fastdfs-client-java.git
mvn clean install

//再pomx文件中配置
<dependency>
    <groupId>org.csource</groupId>
    <artifactId>fastdfs-client-java</artifactId>
    <version>${version}</version>
</dependency>

配置文件

fdfs_client.conf

connect_timeout = 10
network_timeout = 30
charset = UTF-8
http.tracker_http_port = 8888
http.anti_steal_token = no
http.secret_key = FastDFS1234567890

tracker_server = 119.147.xxx.xxx:22122

工具类

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;

import java.io.*;
import java.util.Iterator;
import java.util.Map;

/**
 *  FastDFS分布式文件系统操作客户端
 * @author chennan
 * @date 2018/8/23 17:10
 */
@Slf4j
public class FastDFSClient {

    private static final String CONF_FILENAME = "src/main/resources/fdfs_client.conf";
    private static StorageClient1 storageClient1 = null;


    /**
     * 只加载一次.
     */
    static {
        try {
            log.info(" CONF_FILENAME:" + CONF_FILENAME);
            ClientGlobal.init(CONF_FILENAME);
            TrackerClient trackerClient = new TrackerClient(ClientGlobal.g_tracker_group);
            TrackerServer trackerServer = trackerClient.getConnection();
            if (trackerServer == null) {
                log.error("getConnection return null");
            }
            StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
            if (storageServer == null) {
                log.error("getStoreStorage return null");
            }
            storageClient1 = new StorageClient1(trackerServer, storageServer);
        } catch (Exception e) {
            log.error("连接异常", e);
        }
    }


    /**
     * 上传文件
     * @param file 文件对象
     * @param fileName 文件名
     * @return  返回Null则为失败
     */
    public static String uploadFile(File file, String fileName) {
        return uploadFile(file, fileName, null);
    }
    /**
     * 
     * @param file   文件
     * @param fileName  文件名
     * @param metaList  文件元数据
     * @return   返回Null则为失败
     */
    public static String uploadFile(File file, String fileName,Map<String,String> metaList) {
        FileInputStream fis = null;
        try {
            NameValuePair[] meta_list = null;
            fis = new FileInputStream(file);

            byte[] file_buff = null;
            if (fis != null) {
                int len = fis.available();
                file_buff = new byte[len];
                fis.read(file_buff);
            }

            if (metaList != null) {
                meta_list = new NameValuePair[metaList.size()];
                int index = 0;
                for (Iterator<Map.Entry<String,String>> iterator = metaList.entrySet().iterator(); iterator.hasNext();) {
                    Map.Entry<String,String> entry = iterator.next();
                    String name = entry.getKey();
                    String value = entry.getValue();
                    meta_list[index++] = new NameValuePair(name,value);
                }
            }
            String fileId = storageClient1.upload_file1(file_buff, FilenameUtils.getExtension(fileName), meta_list);

            return fileId;
        } catch (Exception ex) {
            log.error("上传文件失败",ex);
            return null;
        }finally{
            if (fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    log.error("", e);
                }
            }
        }
    }

    /**
     * 根据组名和远程文件名来删除一个文件
     * 
     * @param groupName   例如 "group1" 如果不指定该值,默认为group1
     * @param fileName   例如"M00/00/00/wKgxgk5HbLvfP86RAAAAChd9X1Y736.jpg"
     * @return  0为成功,非0为失败,具体为错误代码
     */
    public static int deleteFile(String groupName, String fileName) {
        try {
            int result = storageClient1.delete_file(groupName == null ? "group1" : groupName, fileName);
            return result;
        } catch (Exception ex) {
            log.error("",ex);
            return 0;
        }
    }

    /**
     * 根据fileId来删除一个文件(我们现在用的就是这样的方式,上传文件时直接将fileId保存在了数据库中)
     * 
     * @param fileId   file_id源码中的解释file_id the file id(including group name and filename);例如 group1/M00/00/00/ooYBAFM6MpmAHM91AAAEgdpiRC0012.xml
     * @return 0为成功,非0为失败,具体为错误代码
     */
    public static int deleteFile(String fileId) {
        try {
            int result = storageClient1.delete_file1(fileId);
            return result;
        } catch (Exception ex) {
            log.error("", ex);
            return 0;
        }
    }

    /**
     * 修改一个已经存在的文件
     * 
     * @param oldFileId  原来旧文件的fileId, file_id源码中的解释file_id the file id(including group name and filename);例如 group1/M00/00/00/ooYBAFM6MpmAHM91AAAEgdpiRC0012.xml
     * @param file   新文件
     * @param filePath 新文件路径
     * @return 返回空则为失败
     */
    public static String modifyFile(String oldFileId, File file, String filePath) {
        String fileId;
        try {
            // 先上传
            fileId = uploadFile(file, filePath);
            if (fileId == null) {
                return null;
            }
            // 再删除
            int delResult = deleteFile(oldFileId);
            if (delResult != 0) {
                return null;
            }
        } catch (Exception ex) {
            log.error("", ex);
            return null;
        }
        return fileId;
    }

    /**
     * 文件下载
     * 
     * @param fileId
     * @return 返回一个流
     */
    public static InputStream downloadFile(String fileId) {
        try {
            byte[] bytes = storageClient1.download_file1(fileId);
            InputStream inputStream = new ByteArrayInputStream(bytes);
            return inputStream;
        } catch (Exception ex) {
            log.error("", ex);
            return null;
        }
    }
}

测试类

import com.zhidian.common.util.FastDFSClient;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.InputStream;


public class FastDFSTest {
    
    /**
     * 上传测试.
     * @throws Exception
     */
    public static void upload() throws Exception {
        String filePath = "D://t1.png";
        File file = new File(filePath);
        String fileId = FastDFSClient.uploadFile(file, filePath);
        System.out.println("Upload local file " + filePath + " ok, fileid=" + fileId);
        // fileId:  group1/M00/00/00/wKhkF1t-hRKAVoa7AAH5AeEMXGQ57.jpeg
        // url: http://119.147.171.111:8888/group1/M00/00/00/wKhkF1t-hRKAVoa7AAH5AeEMXGQ57.jpeg
    }
    
    /**
     * 下载测试.
     * @throws Exception
     */
    public static void download() throws Exception {
        String fileId = "group1/M00/00/00/wKhkF1t-hRKAVoa7AAH5AeEMXGQ57.jpeg";
        InputStream inputStream = FastDFSClient.downloadFile(fileId);
        File destFile = new File("D://DownloadTest.jpg");
        FileUtils.copyInputStreamToFile(inputStream, destFile);
    }

    /**
     * 删除测试
     * @throws Exception
     */
    public static void delete() throws Exception {
        String fileId = "group1/M00/00/00/wKhkF1t-hRKAVoa7AAH5AeEMXGQ57.jpeg";
        int result = FastDFSClient.deleteFile(fileId);
        System.out.println(result == 0 ? "删除成功" : "删除失败:" + result);
    }


    
    /**
     * @param args
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        upload();
        //download();
        //delete();
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容