目錄
安裝FastDFS
centos7安裝FastDFS非常麻煩,而且容易出錯?
java實現文件上傳到服務器,沒思路?
這篇文章詳細介紹如何使用docker+FastDFS+SpringBoot實現分佈式文件上傳系統。
linux安裝FastDFS可參看:https://blog.csdn.net/qq_42937522/article/details/101114411
centos7安裝docker可參看:centos7安裝docker及docker常用命令
FastDFS簡介
FastDFS是一個開源的分佈式文件系統,它對文件進行管理,功能包括:文件存儲、文件同步、文件訪問(文件上傳、文件下載)等,解決了大容量存儲和負載均衡的問題。特別適合以文件爲載體的在線服務,如相冊網站、視頻網站等等。可以說它就是爲互聯網而生,爲大數據而生的。
FastDFS服務端有兩個角色:跟蹤器(tracker)和存儲節點(storage)。跟蹤器主要做調度工作,在訪問上起負載均衡的作用。 存儲節點存儲文件,完成文件管理的所有功能:存儲、同步和提供存取接口,FastDFS同時對文件的meta data進行管理。跟蹤器和存儲節點都可以由多臺服務器構成。跟蹤器和存儲節點中的服務器均可以隨時增加或下線而不會影響線上服務。其中跟蹤器中的所有服務器都是對等的,可以根據服務器的壓力情況隨時增加或減少。
docker安裝FastDFS
1.下載最新的FastDFS鏡像
docker pull delron/fastdfs
2.提前建好需要掛載進容器的目錄
使用mkdir
命令,新建/data/fastdfs/tracker
目錄和/data/fastdfs/storage
目錄。
3.運行容器並掛載目錄
需要分別運行tracker和storage兩個容器。
docker run -di --network=host --name=tracker -v /data/fastdfs/tracker/:/var/fdfs delron/fastdfs tracker
docker run -di --network=host --name storage -e TRACKER_SERVER=ip:22122 -v /data/fastdfs/storage:/var/fdfs -e GROUP_NAME=group1 delron/fastdfs storage
TRACKER_SERVER
是tracker的ip和端口,端口一般是22122,ip需要換成自己的。
4.使用docker ps
查看運行中的容器是否有tracker和storage
如果有,說明運行成功。
5.測試上傳
①進入容器
docker exec -it storage /bin/bash
②默認集成了nginx,可以查看nginx的配置
cd /usr/local/nginx/conf
cat nginx.conf
③查看storage的配置文件
cd /etc/fdfs
cat storage.conf
④storage的配置文件與nginx的端口一致,說明沒有問題
默認端口爲8888
⑤測試上傳文件
將一張圖片放到我們的掛載目錄/data/fastdfs/storage
下,默認會在/var/fdfs
下顯示,因爲有掛載映射。
cd /var/fdfs
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf test.jpg
可通過返回的組信息,查看圖片
瀏覽器輸入路徑:ip:8888/group1/M00/00/00/rBEACF7I6SaAShxXAAXE1JKRK9c745.jpg
即可訪問
SpringBoot+FastDFS搭建分佈式文件上傳系統
1.引入依賴
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.1-RELEASE</version>
</dependency>
2.在application.yml進行配置
#FastDFS相關配置
fdfs:
so-timeout: 1501 # 超時時間
connect-timeout: 601 # 連接超時時間
thumb-image: # 縮略圖設置
width: 60
height: 60
tracker-list: # tracker地址:你的虛擬機服務器地址+端口(默認是22122)
- ip:22122
ip需要替換成自己的ip地址
3.編寫FastDFS的配置類
主要解決以下錯誤,如果沒有,啓動時會報錯
***************************
APPLICATION FAILED TO START
***************************
Description:
Field storageClient in com.blog.module.upload.service.UploadService required a bean of type 'com.github.tobato.fastdfs.service.FastFileStorageClient' that could not be found.
The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.github.tobato.fastdfs.service.FastFileStorageClient' in your configuration.
/**
* Description: FastDFS配置類
*
* 解決jmx重複註冊bean的問題
**/
@Configuration
@Import(FdfsClientConfig.class)
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FastClientImporterConfig {
}
4.編寫UploadController接口
@RestController
@RequestMapping("/api/file")
public class UploadController {
@Autowired
private UploadService uploadService;
/**
* 功能描述:圖片上傳
* 請求參數:文件,參數名是file,SpringMVC會封裝爲一個接口:MultipartFile
* 返回結果:上傳成功後得到的文件的url路徑,也就是返回String
* @param file
* @return 圖片的url地址
*/
@PostMapping("/upload")
public ResponseEntity<String> uploadImage(@RequestParam("file") MultipartFile file{
String url = this.uploadService.upload(file);
//判斷url是否爲空
if(StringUtils.isBlank(url)){
return ResponseEntity.badRequest().build();
}
return ResponseEntity.status(HttpStatus.CREATED).body(url);
}
@DeleteMapping("/")
public ResponseEntity<Void> deleteImage(@RequestParam("filePath") String filePath){
System.out.println(filePath);
this.uploadService.deleteImage(filePath);
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}
}
5.編寫UploadService
@Slf4j
@Service
public class UploadService {
@Autowired
private FastFileStorageClient storageClient;
private static final List<String> CONTENT_TYPES = Arrays.asList("image/jpeg", "image/gif","image/jpg","image/png");
/**
* 圖片上傳
* @param file
* @return
*/
public String upload(MultipartFile file) {
String originalFilename = file.getOriginalFilename();
// 校驗文件的類型
String contentType = file.getContentType();
if (!CONTENT_TYPES.contains(contentType)){
// 文件類型不合法,直接返回null
log.info("文件類型不合法:{}", originalFilename);
return null;
}
try {
// 校驗文件的內容
BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
if (bufferedImage == null){
log.info("文件類型不合法:{}", originalFilename);
return null;
// 保存到服務器,會默認上傳到application.yml配置的ip的服務器
String ext = StringUtils.substringAfterLast(originalFilename, ".");
StorePath storePath = this.storageClient.uploadFile(file.getInputStream(), file.getSize(), ext, null);
// 生成url地址,返回
return "http://ip:8888/" + storePath.getFullPath();
} catch (IOException e) {
log.info("服務器內部錯誤:{}", originalFilename);
e.printStackTrace();
}
return null;
}
/**
* 功能描述: 刪除圖片
*
* @param
* @author jiaoqianjin
* Date: 2020/5/7 21:34
*/
public void deleteImage(String filePath) {
if (StringUtils.isEmpty(filePath)) {
throw new BaseException("圖片路徑不能爲空");
}
//執行刪除圖片
this.storageClient.deleteFile(filePath);
}
}
6.配置完成,可以利用postman進行測試
postman文件請求
①填寫Headers
Key:Content-Type
Value:multipart/form-data
②填寫body
③發送請求
可通過返回的路徑直接進行訪問。