首先安裝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的文件地址,你可以拿着改地址直接保存到數據庫,或者訪問即可
有問題可以在下方留言。