fastdfs服务搭建、集成springboot
2020-06-10 本文已影响0人
X作业写完了吗
对比了几种分布式文件系统,都太适合在线网站,fastdfs现在也不活跃,
推荐开源osshttps://github.com/minio/minio
环境搭建可以参考:
https://github.com/happyfish100/fastdfs/wiki
环境:centos7.x、fastdfs公共函数、fastDFS服务、fast-nginx-module模块、nginx安装
配置、启动、关闭防火墙、测试
测试
$ fdfs_upload_file /etc/fdfs/client.conf /usr/local/rBgeP17gpYqAczWtAAPMRgk1GpU59.jpeg http://172.24.xx.xx:8888/group1/M00/00/00/rBgeP17gpYqAczWtAAPMRgk1GpU59.jpeg
springboot集成fastdfs
client无文档,对照代码的单元测试编写
jar在mvn中央库无法下载,自己安装到本地
克隆https://github.com/happyfish100/fastdfs-client-java
执行mvn clean install ,安装jar到本地maven
<dependency>
<groupId>org.csource</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.29-SNAPSHOT</version>
</dependency>
增加fdfs_client.cong配置文件
connect_timeout = 2
network_timeout = 30
charset = UTF-8
http.tracker_http_port = 8888
#安全校验
http.anti_steal_token = no
http.secret_key = FastDFS1234567890
#必须
tracker_server = 172.24.30.63:22122
connection_pool.enabled = true
connection_pool.max_count_per_entry = 500
connection_pool.max_idle_time = 3600
connection_pool.max_wait_time_in_ms = 1000
初始fastdfs资源类
@Slf4j
@Component
public class FdsStart implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
try {
String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();;
ClientGlobal.init(filePath);
} catch (Exception e) {
log.error("FastDFS Client Init Fail!",e);
}
}
}
service类
@Slf4j
@Component
public class MyFastDFSService {
public String[] upload(MultipartFile mFile) throws IOException, MyException {
StorageClient storageClient = getTrackerClient();
NameValuePair[] metaList = new NameValuePair[3];
String local_filename = mFile.getOriginalFilename();
metaList[0] = new NameValuePair("fileName", local_filename);
metaList[1] = new NameValuePair("width", "600");
metaList[2] = new NameValuePair("height", "800");
int length = mFile.getInputStream().available();
byte[] bytes = new byte[length];
mFile.getInputStream().read(bytes);
String[] result = storageClient.upload_file(bytes, getFilenameExt(local_filename), metaList);
return result;
}
public String[] uploadAppendable(MultipartFile mFile) throws IOException, MyException {
StorageClient storageClient = getTrackerClient();
NameValuePair[] metaList = new NameValuePair[1];
String local_filename = mFile.getOriginalFilename();
metaList[0] = new NameValuePair("fileName", local_filename);
int length = mFile.getInputStream().available();
byte[] bytes = new byte[length];
mFile.getInputStream().read(bytes);
String[] result = storageClient.upload_appender_file(bytes, getFilenameExt(local_filename), metaList);
return result;
}
public Integer append(String groupName, String remoteFileName,String appendText) throws IOException, MyException {
StorageClient storageClient = getTrackerClient();
byte[] file_buff = appendText.getBytes();
return storageClient.append_file(groupName, remoteFileName,file_buff);
}
public InputStream downFile(String groupName, String remoteFileName) throws IOException, MyException {
StorageClient storageClient = getTrackerClient();
byte[] fileByte = storageClient.download_file(groupName, remoteFileName);
return new ByteArrayInputStream(fileByte);
}
public FileInfo getFileInfo(String groupName, String remoteFileName) throws IOException, MyException {
StorageClient storageClient = getTrackerClient();
return storageClient.get_file_info(groupName, remoteFileName);
}
public NameValuePair[] getFileMetadata(String groupName, String remoteFileName) throws IOException, MyException {
StorageClient storageClient = getTrackerClient();
return storageClient.get_metadata(groupName, remoteFileName);
}
public Integer deleteFile(String groupName, String remoteFileName)
throws Exception {
StorageClient storageClient = getTrackerClient();
return storageClient.delete_file(groupName, remoteFileName);
}
public StructGroupStat[] monitorGroup() throws IOException, MyException {
TrackerClient tracker = new TrackerClient();
TrackerServer trackerServer = tracker.getTrackerServer();
if (trackerServer == null) {
return new StructGroupStat[]{};
}
StructGroupStat[] groupStats = tracker.listGroups(trackerServer);
if (groupStats == null) {
log.error("list groups error, error no: " + tracker.getErrorCode());
return new StructGroupStat[]{};
}
return groupStats;
}
public StructStorageStat[] monitorStorage(String group) throws IOException, MyException {
TrackerClient tracker = new TrackerClient();
TrackerServer trackerServer = tracker.getTrackerServer();
if (trackerServer == null) {
return new StructStorageStat[]{};
}
StructStorageStat[] structStorageStats = tracker.listStorages(trackerServer,group);
if (structStorageStats == null) {
log.error("list groups error, error no: " + tracker.getErrorCode());
return new StructStorageStat[]{};
}
return structStorageStats;
}
private StorageClient getTrackerClient() throws IOException {
TrackerServer trackerServer = getTrackerServer();
StorageClient storageClient = new StorageClient(trackerServer, null);
return storageClient;
}
private TrackerServer getTrackerServer() throws IOException {
TrackerClient trackerClient = new TrackerClient();
return trackerClient.getTrackerServer();
}
private static String getFilenameExt(String filename){
return filename.substring(filename.lastIndexOf(".")+1);
}
public String getToken(String filename) throws UnsupportedEncodingException, NoSuchAlgorithmException, MyException {
Long ts = System.currentTimeMillis()/1000;
return ProtoCommon.getToken(filename,ts.intValue(),ClientGlobal.getG_secret_key());
}
}
功能controller
@Slf4j
@RestController
@RequestMapping("/index")
public class WelcomeController {
private String group = "group1";
private Integer deleteSuccess = 0;
@Autowired
private MyFastDFSService myFastDFSService;
/**
* 上传, 上传后图片信息应该与业务数据绑定
* @param file
* @return
* @throws IOException MyException
*/
@RequestMapping(value = {"/upload"},method = RequestMethod.GET)
@WXApiResponseBody
public String upload(@RequestParam("file") MultipartFile file) throws IOException, MyException {
String[] result = myFastDFSService.upload(file);
return result[0] +" , " + result[1];
}
@RequestMapping(value = {"/uploadAppendable"},method = RequestMethod.GET)
@WXApiResponseBody
public String uploadAppendable(@RequestParam("file") MultipartFile file) throws IOException, MyException {
String[] result = myFastDFSService.uploadAppendable(file);
return result[0] +" , " + result[1];
}
@RequestMapping(value = {"/append"},method = RequestMethod.GET)
@WXApiResponseBody
public Integer append(@RequestParam String filename,@RequestParam String text) throws IOException, MyException {
Integer result = myFastDFSService.append(group,filename,text);
return result;
}
/**
* 下载, 如果公开可以直接返回 资源地址
* @param response
* @throws IOException
*/
@RequestMapping(value = {"/download"},method = RequestMethod.GET)
public void down(@RequestParam String filename, HttpServletResponse response) throws IOException, MyException {
InputStream inputStream = myFastDFSService.downFile(group,filename);
response.addHeader("Content-Disposition", "attachment;fileName=" + filename);
byte[] buffer = new byte[1024];
OutputStream outputStream = response.getOutputStream();
int i = inputStream.read(buffer);
while (i != -1) {
outputStream.write(buffer, 0, i);
i = inputStream.read(buffer);
}
}
/**
* 获取文件信息: type 、 size、createTime
* @return
*/
@RequestMapping(value = {"/info"},method = RequestMethod.GET)
@WXApiResponseBody
public String info(@RequestParam String filename) throws IOException, MyException {
FileInfo fileInfo = myFastDFSService.getFileInfo(group,filename);
return fileInfo.toString();
}
/**
* 获取文件信息: metadata
* @return
*/
@RequestMapping(value = {"/metadata"},method = RequestMethod.GET)
@WXApiResponseBody
public String metadata(@RequestParam String filename) throws IOException, MyException {
NameValuePair[] metadatas = myFastDFSService.getFileMetadata(group,filename);
return Arrays.stream(metadatas).map(e->{
return e.getName() +":" + e.getValue();
}).collect(Collectors.joining(","));
}
/**
* 删除, 资源删除的情况下 应该在业务代码中处理
* @param filename
* @throws Exception
*/
@RequestMapping(value = {"/delete"},method = RequestMethod.GET)
@WXApiResponseBody
public Boolean delete(@RequestParam String filename) throws Exception {
return deleteSuccess.equals(myFastDFSService.deleteFile(group,filename));
}
@RequestMapping(value = {"/mGroup"},method = RequestMethod.GET)
@WXApiResponseBody
public StructGroupStat[] monitorGroup() throws Exception {
return myFastDFSService.monitorGroup();
}
@RequestMapping(value = {"/mStorage"},method = RequestMethod.GET)
@WXApiResponseBody
public StructStorageStat[] monitorStorage() throws Exception {
return myFastDFSService.monitorStorage(group);
}
}
现在基本完成了fastdfs的体验,具体需求根据业务处理。
比如数据要存库, 业务数据与文件相关属性绑定。