Docker 安裝 fastdfs,後臺實現文件上傳

首先安裝Docker ,在前篇播客中介紹怎樣安裝Docker ,可以去看一下,我安裝的Docker 是基於Ubuntu安裝的,不喜歡的小夥伴可以使用Centos進行安裝,下面是我的環境 。

首先在usr目錄下面創建一系列文件,文件順序在上圖中可以看到,當然也可以自己創建。進入該文件,進行創建docker-compose.yml文件該文件是在第一層fastdfs的目錄下

下面開始查看docker-compose.yml 文件

第一個fastdfs,表示當前容器依賴那個容器,build 表示構建數據卷,Dockerfile 文件,restart 表示服務重啓之後,該服務也會重啓,container_name  表示,當前容器的名稱,volumes: 表示 將數據卷 進行映射,將fastdfs/storage 文件 映射到 自己定義的文件中。下面進入fastdfs 文件,進行查看Dockerfile文件

需要將這些文件,拷貝到當前目錄下,碼雲地址:https://gitee.com/sgqing/fastdfsPeiZhiWenJian.git

下面開始配置這寫文件,其中上圖 中的 文件 1 是不存在的, 在運行之後生成的應該是,修改當前的配置文件主要是修改裏面的服務的ip地址,修改成你當前虛擬機的地址,並且把url進行修改成指定的文件的地址

client.conf 文件,進行修改下面兩處,修改完成之後,保存退出

config文件,如果使用我提供的話,直接使用接即可,如果不是需要將local 去除掉

entrypoint.sh 文件,首先 使用 chmod -x entrypoint.sh  將當前文件修改成 可執行文件,也不需要配置

該文件裏面的配置是,在啓動的時候,就會啓動 fdfs 的 trackerd 和 storaged 

mod_fastdfs.conf 文件,也是修改 ip地址  和  path地址

  

nginx.conf 文件,如果使用我提供的文件不需要進行修改,如果不是,需要修改下面的配置

storage.conf 文件,需要修改三個地方,好好找找,不太好找

tracker.conf 文件, 修改路徑

上面是修改的全部的文件,下面開始配置Dockerfile 文件,下面是配置,版本最好是用我提供的,不然會出現錯誤,下面配置就不進行說明,拷貝過去可直接用

FROM ubuntu:xenial
MAINTAINER [email protected]

# 更新數據源
WORKDIR /etc/apt
RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse' > sources.list
RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse' >> sources.list
RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse' >> sources.list
RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse' >> sources.list
RUN apt-get update

# 安裝依賴
RUN apt-get install make gcc libpcre3-dev zlib1g-dev --assume-yes

# 複製工具包
ADD fastdfs-5.11.tar.gz /usr/local/src
ADD fastdfs-nginx-module_v1.16.tar.gz /usr/local/src
ADD libfastcommon.tar.gz /usr/local/src
ADD nginx-1.13.6.tar.gz /usr/local/src

# 安裝 libfastcommon
WORKDIR /usr/local/src/libfastcommon
RUN ./make.sh && ./make.sh install

# 安裝 FastDFS
WORKDIR /usr/local/src/fastdfs-5.11
RUN ./make.sh && ./make.sh install

# 配置 FastDFS 跟蹤器
ADD tracker.conf /etc/fdfs
RUN mkdir -p /fastdfs/tracker

# 配置 FastDFS 存儲
ADD storage.conf /etc/fdfs
RUN mkdir -p /fastdfs/storage

# 配置 FastDFS 客戶端
ADD client.conf /etc/fdfs

# 配置 fastdfs-nginx-module
ADD config /usr/local/src/fastdfs-nginx-module/src

# FastDFS 與 Nginx 集成
WORKDIR /usr/local/src/nginx-1.13.6
RUN ./configure --add-module=/usr/local/src/fastdfs-nginx-module/src
RUN make && make install
ADD mod_fastdfs.conf /etc/fdfs

WORKDIR /usr/local/src/fastdfs-5.11/conf
RUN cp http.conf mime.types /etc/fdfs/

# 配置 Nginx
ADD nginx.conf /usr/local/nginx/conf

COPY entrypoint.sh /usr/local/bin/
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

WORKDIR /
EXPOSE 8888
CMD ["/bin/bash"]

完成上面配置之後,即可保存退出,返回到上一級目錄,然後使用 docker-compose up -d 後臺運行,執行成功,還有一點,咱們在配置文件中配置了nginx,端口是8888

 

安裝完成之後,開始進入java 端的開發 ,我這裏使用的是 idea ,spring boot starter 是 1.5版本

首先引入fastdfs的maven 的依賴

 <!-- FastDFS Begin -->
            <dependency>
                <groupId>org.csource</groupId>
                <artifactId>fastdfs-client-java</artifactId>
                <version>1.27-SNAPSHOT</version>
            </dependency>
            <!-- FastDFS End -->

當然,因爲fastdfs在倉庫中是沒有的,需要將當前依賴手動的安裝到本地的倉庫中,然後重新加載,可能需要多試幾次,跟編譯器。電腦有關係,我試了很多次,一直加載不進來

首先使用git進行下載:使用下面的git地址,

git clone https://github.com/happyfish100/fastdfs-client-java.git

下載到本地之後,進入下面的目錄中,當然不用注意我的.idea 和.git 文件,我的是因爲idea加載不進來,然後將當前文件用idea打開之後,使用mvn 的命令 進行安裝,install之後,確實是可以了,也可以試一下

進行入之後,在當前目錄打開 cmd 然後使用  mvn clean install 進行安裝,當提示安裝完成之後們就會在你指定的環境變量中的 MAVEN_HOME  的路徑下的maven下的 conf下面的setting.xml 文件中配置的 倉庫地址中生成指定的 文件,生成下面文件

此時再去idea 中進行加載該依賴。

完成上面的配置之後,下面開始完成代碼上傳,我用的前端框架是Metronic 框架,但是很多框架都是一樣的,在文件上傳的組件中都會設置上傳文件的name 和action ,大致相同,你可以隨便使用,是要上傳文件的name 和 action 上傳文件的參數的名稱一致即可,下面的配置文件網上有很多,下面是我使用的,直接拷貝即可。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FastDFSConfiguration {

    @Bean
    public StorageFactory storageFactory(){
        return new StorageFactory();
    }
}
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class FastDFSStorageService implements StorageService, InitializingBean {

    private static final Logger logger = LoggerFactory.getLogger(FastDFSStorageService.class);

    private TrackerClient trackerClient;

    @Value("${storage.fastdfs.tracker_server}")
    private String trackerServer;

    @Override
    public String upload(byte[] data, String extName) {
        TrackerServer trackerServer = null;
        StorageServer storageServer = null;
        StorageClient1 storageClient1 = null;
        try {
            NameValuePair[] meta_list = null; // new NameValuePair[0];

            trackerServer = trackerClient.getConnection();
            if (trackerServer == null) {
                logger.error("getConnection return null");
            }
            storageServer = trackerClient.getStoreStorage(trackerServer);
            storageClient1 = new StorageClient1(trackerServer, storageServer);
            String fileid = storageClient1.upload_file1(data, extName, meta_list);
            logger.debug("uploaded file <{}>", fileid);
            return fileid;
        } catch (Exception ex) {
            logger.error("Upload fail", ex);
            return null;
        } finally {
            if (storageServer != null) {
                try {
                    storageServer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (trackerServer != null) {
                try {
                    trackerServer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            storageClient1 = null;
        }
    }

    @Override
    public int delete(String fileId) {
//        System.out.println("deleting ....");
        TrackerServer trackerServer = null;
        StorageServer storageServer = null;
        StorageClient1 storageClient1 = null;
        int index = fileId.indexOf('/');
        String groupName = fileId.substring(0, index);
        try {
            trackerServer = trackerClient.getConnection();
            if (trackerServer == null) {
                logger.error("getConnection return null");
            }
            storageServer = trackerClient.getStoreStorage(trackerServer, groupName);
            storageClient1 = new StorageClient1(trackerServer, storageServer);
            int result = storageClient1.delete_file1(fileId);
            return result;
        } catch (Exception ex) {
            logger.error("Delete fail", ex);
            return 1;
        } finally {
            if (storageServer != null) {
                try {
                    storageServer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (trackerServer != null) {
                try {
                    trackerServer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            storageClient1 = null;
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        File confFile = File.createTempFile("fastdfs", ".conf");
        PrintWriter confWriter = new PrintWriter(new FileWriter(confFile));
        confWriter.println("tracker_server=" + trackerServer);
        confWriter.close();
        ClientGlobal.init(confFile.getAbsolutePath());
        confFile.delete();
        TrackerGroup trackerGroup = ClientGlobal.g_tracker_group;
        trackerClient = new TrackerClient(trackerGroup);

        logger.info("Init FastDFS with tracker_server : {}", trackerServer);
    }
}
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;

import java.util.HashMap;
import java.util.Map;

public class StorageFactory implements FactoryBean<StorageService> {
    @Autowired
    private AutowireCapableBeanFactory acbf;

    /**
     * 存儲服務的類型,目前僅支持fastdfs
     */
    @Value("${storage.type}")
    private String type;

    private Map<String, Class<? extends StorageService>> classMap;

    public StorageFactory() {
        classMap = new HashMap<>();
        classMap.put("fastdfs", FastDFSStorageService.class);
    }

    @Override
    public StorageService getObject() throws Exception {
        Class<? extends StorageService> clazz = classMap.get(type);
        if (clazz == null) {
            throw new RuntimeException("Unsupported storage type [" + type + "], valid are " + classMap.keySet());
        }

        StorageService bean = clazz.newInstance();
        acbf.autowireBean(bean);
        acbf.initializeBean(bean, bean.getClass().getSimpleName());
        return bean;
    }

    @Override
    public Class<?> getObjectType() {
        return StorageService.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}
public interface StorageService {
    /**
     * 上傳文件
     *
     * @param data    文件的二進制內容
     * @param extName 擴展名
     * @return 上傳成功後返回生成的文件id;失敗,返回null
     */
    public String upload(byte[] data, String extName);

    /**
     * 刪除文件
     *
     * @param fileId 被刪除的文件id
     * @return 刪除成功後返回0,失敗後返回錯誤代碼
     */
    public int delete(String fileId);
}
import com.google.common.collect.Maps;
import com.ooqui.gaming.service.web.admin.gamingserverwebadmin.config.fastdfs.StorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import utils.MapperUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Controller
public class UploadController {
    @Value("${fastdfs.base.url}")
    private String FASTDFS_BASE_URL;

    @Autowired
    private StorageService storageService;

    @ResponseBody
    @RequestMapping("upload")
    public String upload(MultipartFile uploadFile, MultipartFile wangEditorH5File) {
        if (uploadFile != null) {
            String oName = uploadFile.getOriginalFilename();
            String extName = oName.substring(oName.indexOf(".") + 1);
            HashMap<String, Object> map = new HashMap<>();

            try {
                String uploadUrl = storageService.upload(uploadFile.getBytes(), extName);
                map.put("success", "上傳成功");
                map.put("url", FASTDFS_BASE_URL + uploadUrl);
            } catch (IOException e) {
                map.put("error", 1);
                map.put("message", "上傳失敗");
            }

            return MapperUtils.mapToJson(map);
        } else if (wangEditorH5File != null) {
            String oName = wangEditorH5File.getOriginalFilename();
            String extName = oName.substring(oName.indexOf(".") + 1);

            Map<String, Object> map = Maps.newHashMap();

            try {
                String uploadUrl = storageService.upload(wangEditorH5File.getBytes(), extName);
                String url = FASTDFS_BASE_URL + uploadUrl;

                // 上傳成功
                map.put("errno", 0);
                map.put("data", new String[]{url});
            } catch (IOException e) {
                // 上傳失敗
                map.put("errno", 1);
                map.put("message", "服務端錯誤");
            }

            return MapperUtils.mapToJson(map);
        }

        return "";
    }
}

上面是用到的java 文件,這些文件都是官網提供好的,我也是直接拷貝過來使用的,html的代碼我就不展示了,你只要只一個可用的前端框架,在框架中會有action 和 name 屬性的配置,我這邊的action的路徑是 /upload,上傳文件的名稱是  uploadFile

你只要將這兩個參數進行傳遞即可完成文件上傳,當然,在文件上傳成功之後,會返回你上傳文件的路徑,路徑是你上傳服務器的地址加上fastdfs的文件地址,你可以拿着改地址直接保存到數據庫,或者訪問即可

有問題可以在下方留言。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章