zoukankan      html  css  js  c++  java
  • FastDFS

    FastDFS 是用 c 语言编写的一款开源的分布式文件系统。FastDFS 为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用 FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

    FastDFS 架构包括 Tracker server 和 Storage server。客户端请求 Tracker server 进行文件上传、下载,通过 Tracker server 调度最终由 Storage server 完成文件上传和下载。

    Tracker server 作用是负载均衡和调度,通过 Tracker server 在文件上传时可以根据一些策略找到 Storage server 提供文件上传服务。可以将 tracker 称为追踪服务器或调度服务器。

    Storage server 作用是文件存储,客户端上传的文件最终存储在 Storage 服务器上,Storageserver 没有实现自己的文件系统而是利用操作系统 的文件系统来管理文件。可以将storage称为存储服务器。

    服务端两个角色:

    Tracker:管理集群,tracker 也可以实现集群。每个 tracker 节点地位平等。收集 Storage 集群的状态。

    Storage:实际保存文件   Storage 分为多个组,每个组之间保存的文件是不同的。每个组内部可以有多个成员,组成员内部保存的内容是一样的,组成员的地位是一致的,没有主从的概念

    文件上传流程

    客户端上传文件后存储服务器将文件 ID 返回给客户端,此文件 ID 用于以后访问该文件的索引信息。文件索引信息包括:组名,虚拟磁盘路径,数据两级目录,文件名。

    组名:文件上传后所在的 storage 组名称,在文件上传成功后有 storage 服务器返回,需要客户端自行保存。

    虚拟磁盘路径:storage 配置的虚拟路径,与磁盘选项 store_path*对应。如果配置了

    store_path0 则是 M00,如果配置了 store_path1 则是 M01,以此类推

     数据两级目录:storage 服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件。

    文件名:与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储

    服务器 IP 地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息。

    文件下载流程:

      FastDFS 架构(简单版)

     FastDFS入门:

    需求:将本地图片上传至图片服务器,再控制台打印url

    (1)创建Maven工程fastDFSdemo

    由于FastDFS客户端jar包并没有在中央仓库中,所以需要使用下列命令手动安装jar包到Maven本地仓库(改成自己的目录)

    mvn install:install-file -DgroupId=org.csource.fastdfs -DartifactId=fastdfs  -Dversion=1.2 -Dpackaging=jar -Dfile=d:setupfastdfs_client_v1.20.jar

    pom.xml中引入

    <dependency>
    	    <groupId>org.csource.fastdfs</groupId>
    	    <artifactId>fastdfs</artifactId>
    	    <version>1.2</version>
    	</dependency>

    添加配置文件fdfs_client.conf 

     测试代码:

    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    import org.csource.fastdfs.ClientGlobal;
    import org.csource.fastdfs.StorageClient;
    import org.csource.fastdfs.StorageServer;
    import org.csource.fastdfs.TrackerClient;
    import org.csource.fastdfs.TrackerServer;
    
    public class Test {
    
    	public static void main(String[] args) throws FileNotFoundException, IOException, Exception {
    		// 1.加载配置文件
    		ClientGlobal.init("D:\pinyougou_bigdata1\fastDFSdemo\src\main\resources\fdfs_client.conf");
    		// 2.构建一个管理者客户端
    		TrackerClient client=new TrackerClient();
    		// 3.连接管理者服务端
    		TrackerServer trackerServer = client.getConnection();
    		//4. 声明存储服务端
    		StorageServer storageServer=null;
    		//5. 获取存储服务器的客户端对象
    		StorageClient storageClient=new StorageClient(trackerServer, storageServer);
    		//6.上传文件
    		String[] strings = storageClient.upload_file("e:\image\b.jpg", "jpg", null);
    		//7.显示上传结果 file_id
    		for(String str:strings){
    			System.out.println(str);
    		}			
    	}
    }
    

      封装成工具类:

    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 {
    		if (conf.contains("classpath:")) {
    			conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());
    		}
    		ClientGlobal.init(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(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);
    	}
    }
    

    在application.properties:

    FILE_SERVER_URL=http://192.168.25.133/  

    在springmvc.xml中添加配置:

    <!-- 配置多媒体解析器 -->
    	<bean id="multipartResolver"
    		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    		<property name="defaultEncoding" value="UTF-8"></property>
    		<!-- 设定文件上传的最大值 5MB,5*1024*1024 -->
    		<property name="maxUploadSize" value="5242880"></property>
    	</bean>
    

      控制器:

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    
    import entity.Result;
    import util.FastDFSClient;
    
    @RestController
    public class UploadController {
    	@Value("${FILE_SERVER_URL}")
    	private String file_server_url;
    
    	@RequestMapping("/upload")
    	public Result upload(MultipartFile file){
    		
    		String originalFilename = file.getOriginalFilename();//获取文件名
    		String extName=originalFilename.substring( originalFilename.lastIndexOf(".")+1);//得到扩展名
    		
    		try {
    			util.FastDFSClient client=new FastDFSClient("classpath:config/fdfs_client.conf");
    			String fileId = client.uploadFile(file.getBytes(), extName);
    			String url=file_server_url+fileId;//图片完整地址
    			return new Result(true, url);
    			
    		} catch (Exception e) {
    			e.printStackTrace();
    			return new Result(false, "上传失败");
    		}
    	}
    }
    

      前端service:

    app.service('uploadService',function($http){
    	//上传文件
    	this.uploadFile=function(){
    		var formdata=new FormData();
    		formdata.append('file',file.files[0]);//file 文件上传框的name
    		
    		return $http({
    			url:'../upload.do',		
    			method:'post',
    			data:formdata,
    			headers:{ 'Content-Type':undefined },
    			transformRequest: angular.identity			
    		});
    	}
    });
    

      

  • 相关阅读:
    perl 解json数组
    华为云3大体系化防护实践,保障金融业云上数据安全
    弹性文件服务解密 -- 块存储、文件存储、对象存储的区别
    【nodejs原理&源码赏析(6)】深度剖析cluster模块源码与node.js多进程
    云+AI+5G时代,华为云已准备好多元化云服务架构
    高能街访 | 为什么他们都纷纷为深圳打Call?
    Angularjs进阶笔记(2)—自定义指令中的数据绑定
    Angularjs进阶笔记(1)—不同类型的双向数据绑定
    ServiceComb java-chassis和CSE java-chassis的区别
    使用inspector功能查看和管理契约
  • 原文地址:https://www.cnblogs.com/sunliyuan/p/12499752.html
Copyright © 2011-2022 走看看