平常開發難免會需要圖片的上傳和下載,所以搭建一個自己的圖片服務器是很必要的。不僅僅便於後端存儲只需要存url,前端也可以直接通過url展示圖片。
搭建一個新的服務可能還會影響到其他服務的配置,所以這裏強烈推薦使用docker進行部署。部署過程其實還是挺簡單的,只是可能還是會有一些不經意的坑會踩。這裏就簡單分享一下搭建流程。
安裝docker
因爲我的服務器是Ubuntu所以直接使用下面的命令就可以了
apt install docker.io
這裏安裝完後可能使用docker還不會有提示,需要關掉當前的shell,重新連接,再次進入就會有docker的命令提示了。
但是,因爲docker默認是需要root才能執行的,爲避免麻煩每次輸入sudo,這裏可以設置一下用戶組。
sudo usermod -a -G docker $USER
這裏使用id查看一下就會顯示當前用戶的group多了一個docker,同樣需要重新打開shell,再次使用docker命令就不用再輸入sudo了。
搭建fastDFS
基本配置
搜索需要的鏡像
docker search fastdfs
這裏我們需選擇delron/fastdfs,因爲這個鏡像包含了我們需要的Nginx。
在pull鏡像之前我們可以對我們的docker源配置爲國內的源,避免下載太慢。docker下載好後有時候沒有daemon.json,我直接新建一個就好。
sudo vim /etc/docker/daemon.json
然後拷貝下面的內容
#這裏可以連添加多個源,一般一個就夠了
{
"registry-mirrors": ["https://km0lwhqm.mirror.aliyuncs.com", "http://hub-mirror.c.163.com", "https://registry.docker-cn.com"]
}
修改完後,需要重新加載我們的配置文件:(這裏也可以直接使用 sudo systemctl restart docker 對docker進行重啓,如不想停掉docker中其他的服務就使用下面的命令進行加載配置文件)
sudo systemctl daemon-reload
配置完成後就可以進行pull操作了
docker pull delron/fastdfs
啓動tracker:這裏的-v的參數前面是實際數據映射的路徑,可以根據自己的需要定義。
docker run -d --network=host --name tracker -v /home/tracker:/var/fdfs delron/fastdfs tracker
啓動storage:這裏的ip需要時公網ip否則否面上傳圖片可能會報錯。
docker run -d --network=host --name storage -e TRACKER_SERVER=你自己的公網IP:22122 -v /home/storage:/var/fdfs -e GROUP_NAME=group1 delron/fastdfs storage
其實到這裏我們的fastDFS服務的配置已經基本完成了。
測試
我們可以測試一下,直接從本地拷貝一張圖片到剛纔我們配置的 /home/storage/ 路徑下上傳一張圖片,用於後面的測試。
然後進入storage: docker exec -it storage bash;切換到內部映射路徑下:cd /var/fdfs/
可以看到我們映射的路徑下有對應的圖片,我們使用命令進行一次上傳操作:/usr/bin/fdfs_upload_file /etc/fdfs/client.conf <你自己的圖片>
上傳成功後我們會得到一個路徑,拼上對應的ip和端口(默認8888)訪問一下
http://你的ip:8888/group1/M00/00/00/wKgAnl5gzK6ALRs6AABrOeFd0Ug370.png
端口問題:如果使用的是默認的配置那麼,fastdfs的端口分別是8888,22122,23000這三個端口。
這裏我們只需要在我們服務器控制檯的安全組配置中加入對應的端口就可以了。
整合SpringBoot
1.新建一個SpringBoot項目
2.加入依賴
<!--fastDFS-->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.2</version>
</dependency>
3.配置yml文件
# ===================================================================
# 分佈式文件系統FDFS配置
# ===================================================================
fdfs:
so-timeout: 15001
connect-timeout: 15001
thumb-image: #縮略圖生成參數,一般頭像使用,根據需求配置
width: 80
height: 80
tracker-list[0]: 你的服務的ip:22122
4.構建一個client
package com.clf.miniwechat.utils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.exception.FdfsUnsupportStorePathException;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
@Component
public class FastDFSClient {
@Autowired
private FastFileStorageClient storageClient;
/**
* 上傳文件
*
* @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 storePath.getPath();
}
public String uploadFile2(MultipartFile file) throws IOException {
StorePath storePath = storageClient.uploadImageAndCrtThumbImage(file.getInputStream(), file.getSize(),
FilenameUtils.getExtension(file.getOriginalFilename()), null);
return storePath.getPath();
}
public String uploadQRCode(MultipartFile file) throws IOException {
StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(),
"png", null);
return storePath.getPath();
}
public String uploadFace(MultipartFile file) throws IOException {
StorePath storePath = storageClient.uploadImageAndCrtThumbImage(file.getInputStream(), file.getSize(),
"png", null);
return storePath.getPath();
}
public String uploadBase64(MultipartFile file) throws IOException {
StorePath storePath = storageClient.uploadImageAndCrtThumbImage(file.getInputStream(), file.getSize(),
"png", null);
return storePath.getPath();
}
/**
* 將一段字符串生成一個文件上傳
*
* @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 storePath.getPath();
}
/**
* 刪除文件
*
* @param fileUrl
* 文件訪問地址
* @return
*/
public void deleteFile(String fileUrl) {
if (StringUtils.isEmpty(fileUrl)) {
return;
}
try {
StorePath storePath = StorePath.praseFromUrl(fileUrl);
storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
} catch (FdfsUnsupportStorePathException e) {
e.getMessage();
}
}
}
5.最後在test中進行測試