fastDFS分佈式文件系統
什麼是fastDFS
fastDFS是一個底層使用C語言編寫並且開源的, 分佈式文件系統
作用:可以統一管理存儲服務器集羣, 統一管理存儲讀取文件.
fastDFS的原理
fastDFS原理(工作流程)
- fastDFS一共分爲三部分, client客戶端(我們的項目), trackerServer管理端, storageServer存儲端
- client客戶端(我們的項目): 使用fastDFS的jar包中的api來存儲文件,調用fastDFS
- trackerServer管理端:管理storageServer存儲端集羣的, 管理端如果死掉存儲端無法使用, 所以管理端都是做雙機熱備, 就是一臺主機, 一臺備機, 他們之間做心跳檢測機制, 平時主機工作, 備機向主機發送ping命令, 主機接收到後返回pong命令, 如果一段時間內沒有返回, 備機會認爲主機死掉會替代主機工作.這樣可以保證管理端的高可用. 管理端還有負載均衡的功能, 可以平均分配請求給存儲端. 這樣就可以承載高併發的存儲需求.
- storageServer存儲端: 它負責具體存儲文件, 也是兩臺爲一組, 一臺主機一臺備機, 之間雙機熱備, 做心跳檢測.保證存儲端的高可用. 存儲端做冗餘存儲, 就是我們向存儲端主機存儲內容, 主機會向備機發送內容,主機和備機存儲的內容是一樣的, 所以主機即使壞掉, 備機也有同樣的內容可以使用.這種叫容災配置.存儲端理論上存儲容量是無限的, 因爲兩臺爲一組機器可以無限擴展.
工作流程: 我們項目存儲的時候先調用管理端, 管理端會給我們分配一臺存儲端的IP地址和端口, 我們向存儲端機器存儲文件, 存儲端會給我們返回存儲後的地址以及文件名, 文件名會自動被存儲端重命名, 防止文件重名
優點:
- 管理端有負載均衡的功能, 可以承載高併發的存儲需求
- 存儲端可以無限擴展, 理論上存儲容量是無限的, 擴展性好
- 存儲端和管理端都使用了心跳檢測機制, 保證了服務器的高可用
- 存儲端做了冗餘存儲, 所以即使有機器壞掉也不會丟數據, 容災性好
缺點: fastDFS結構複雜, 會使項目中的複雜度變高, 並且搭建fastDFS會使用很多服務器, 比較貴.
fastDFS的例子
一、創建Maven的普通項目
二、引入依賴:注意fastDFS的jar包在maven中央倉庫中沒有,需要去fastDFS的官網下載,然後執行命令
mvn install:install-file -DgroupId=org.csource.fastdfs -DartifactId=fastdfs -Dversion=1.2 -Dpackaging=jar -Dfile=d:\setup\fastdfs_client_v1.20.jar
<dependency>
<groupId>org.csource.fastdfs</groupId>
<artifactId>fastdfs</artifactId>
<version>1.2</version>
</dependency>
三、添加配置文件:fdfs_client.conf
,注意文件名不能改動
# connect timeout in seconds
# default value is 30s
connect_timeout=30
# network timeout in seconds
# default value is 30s
network_timeout=60
# the base path to store log files
base_path=/home/fastdfs
# tracker_server can ocur more than once, and tracker_server format is
# "host:port", host can be hostname or ip address
tracker_server=192.168.200.128:22122
#standard log level as syslog, case insensitive, value list:
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=info
# if use connection pool
# default value is false
# since V4.05
use_connection_pool = false
# connections whose the idle time exceeds this time will be closed
# unit: second
# default value is 3600
# since V4.05
connection_pool_max_idle_time = 3600
# if load FastDFS parameters from tracker server
# since V4.05
# default value is false
load_fdfs_parameters_from_tracker=false
# if use storage ID instead of IP address
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# default value is false
# since V4.05
use_storage_id = false
# specify storage ids filename, can use relative or absolute path
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# since V4.05
storage_ids_filename = storage_ids.conf
#HTTP settings
http.tracker_server_port=80
#use "#include" directive to include HTTP other settiongs
##include http.conf
四、代碼實現
- 加載配置文件(絕對路徑)
- 創建管理端對象
- 通過管理端對象獲取連接
- 創建存儲端對象
- 上傳文件
package cn.itcast.test;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient1;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
public class TestFastDFS {
public static void main(String[] args) throws Exception {
//1.加載配置文件
ClientGlobal.init("D:\\Program Files\\IDEA Projects\\fastDFSDemo\\src\\main\\resources\\fdfs_client.conf");
//2.創建管理端對象
TrackerClient trackerClient = new TrackerClient();
//3.通過管理端對象獲取連接
TrackerServer connection = trackerClient.getConnection();
//4.創建存儲端對象
StorageClient1 storageClient1 = new StorageClient1(connection,null);
//創建文件屬性信息對象數組
NameValuePair[] meta_list = new NameValuePair[3];
meta_list[0] = new NameValuePair("fileName","1");
meta_list[1] = new NameValuePair("ExtName","png");
meta_list[2] = new NameValuePair("author","sm");
//5.上傳文件
String path = storageClient1.upload_file1("D:\\1.png", "png", meta_list);
System.out.println(path);// group1/M00/00/01/wKjIgF7cceeAC36TAAAftfpwV-E664.png
}
}
五、訪問圖片
http://192.168.200.128/group1/M00/00/01/wKjIgF7cceeAC36TAAAftfpwV-E664.png
fastDFS工具類
package cn.itcast.core.util;
import org.apache.commons.io.FilenameUtils;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient1;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
public class FastDFSClient {
private TrackerClient trackerClient = null;
private TrackerServer trackerServer = null;
private StorageServer storageServer = null;
private StorageClient1 storageClient = null;
public FastDFSClient(String conf) throws Exception {
ClientGlobal.init("D:\\Program Files\\IDEA Projects\\pyg_parent\\web_shop\\src\\main\\resources\\fastDFS\\fdfs_client.conf");
trackerClient = new TrackerClient();
trackerServer = trackerClient.getConnection();
storageServer = null;
storageClient = new StorageClient1(trackerServer, storageServer);
}
/**
* 上傳文件方法
* <p>Title: uploadFile</p>
* <p>Description: </p>
* @param fileName 文件全路徑
* @param extName 文件擴展名,不包含(.)
* @param metas 文件擴展信息
* @return
* @throws Exception
*/
public String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception {
String result = storageClient.upload_file1(fileName, extName, metas);
return result;
}
/**
*這個比較好用
*/
public String uploadFile(byte[] file, String fileName, long fileSize) throws Exception {
NameValuePair[] metas = new NameValuePair[3];
metas[0] = new NameValuePair("fileName", fileName);
metas[1] = new NameValuePair("fileSize", String.valueOf(fileSize));
metas[2] = new NameValuePair("fileExt", FilenameUtils.getExtension(fileName));
String result = storageClient.upload_file1(file, FilenameUtils.getExtension(fileName), metas);
return result;
}
public String uploadFile(String fileName) throws Exception {
return uploadFile(fileName, null, null);
}
public String uploadFile(String fileName, String extName) throws Exception {
return uploadFile(fileName, extName, null);
}
/**
* 上傳文件方法
* <p>Title: uploadFile</p>
* <p>Description: </p>
* @param fileContent 文件的內容,字節數組
* @param extName 文件擴展名
* @param metas 文件擴展信息
* @return
* @throws Exception
*/
public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) throws Exception {
String result = storageClient.upload_file1(fileContent, extName, metas);
return result;
}
public String uploadFile(byte[] fileContent) throws Exception {
return uploadFile(fileContent, null, null);
}
public String uploadFile(byte[] fileContent, String extName) throws Exception {
return uploadFile(fileContent, extName, null);
}
}
文件上傳
/**
* 文件上傳
*/
@RestController
@RequestMapping("/upload")
public class UploadController {
/**
* 讀取application.properties配置文件內容,通過裏面的key,FILE_SERVER_URL,讀取值並賦值給FILE_SERVER
*/
@Value("${FILE_SERVER_URL}")
private String FILE_SERVER;
@RequestMapping("/uploadFile")
public Result uploadFile(MultipartFile file) throws Exception {
try {
FastDFSClient fastDFS = new FastDFSClient("classpath:fastDFS/fdfs_client.conf");
//上傳文件,返回文件保存的路徑和文件名
String path = fastDFS.uploadFile(file.getBytes(), file.getOriginalFilename(), file.getSize());
return new Result(true,FILE_SERVER+path);
} catch (Exception e) {
e.printStackTrace();
return new Result(false,"上傳失敗!");
}
}
}
Java中json的轉換
使用阿里的fastjson
一、將json格式的數組字符串轉化成List集合
JSON.parseArray
將json格式字符串轉換成List集合
二、將json格式字符串轉換成實體對象
JSON.parseObject
將json格式字符串轉換成pojo或map對象