springclod_06_fastdfs图片统一处理

前言

一、图片统一处理

1、图片统一处理的原因

springclod_06_fastdfs图片统一处理_第1张图片

2、方案选择

选择合适分布式集群文件系统:安全,可以备份,统一处理的,避免了文件放置某一个服务器,不能集群的问题.

(1)租

阿里云、七牛云…

(2)

自己搭建服务器
在这里插入图片描述

(3)图片统一处理的示意图

就是上面的原因图示

3、Fastdfs概念

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

4、FastDFS 架构包括两部分

(1)客户端请求:Tracker server

管理集群 。客户端请求 Tracker server 进行文件上传、下载,通过 Tracker server 调度最终由 Storage server 完成文件上传和下载。
Tracker server 作用是负载均衡和调度,通过 Tracker server 在文件上传时可以根据一些策略找到 Storage server 提供文件上传服务。可以将 tracker 称为追踪服务器或调度服务器。

(2)存储服务器:Storage server

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

5、Fastdfs的下载

maven不能自动到中央仓库下载Fastdfs依赖包。要在Github上下载压缩包,并配置在maven仓库中,然后引入pom.xml文件才能使用

下载fastdfs的压缩包

  • 下载流程图
    springclod_06_fastdfs图片统一处理_第2张图片
  • 打包流程图
    springclod_06_fastdfs图片统一处理_第3张图片

二、项目中使用

1、概要

springclod_06_fastdfs图片统一处理_第4张图片

  • 封装成一个公共服务
    和redis一样:先搞服务提供者
    消费者:是通过页面来进行图片的上传和下载,我们应该通过网关暴露接口。

2、在项目中使用

(1)先在公共服务模块aigou_common_service_6699的pom.xml中导入fastdfs的依赖包

在增加个文件操作的工具依赖



    org.csource
    fastdfs-client-java
    1.27-SNAPSHOT



    commons-io
    commons-io
    2.6

(2)再在公共服务aigou_common_interface接口模块中写fastdfs的接口。FastDfsClient

@FeignClient(value="COMMON-PROVIDER",fallback = FastDfsFall.class)
public interface FastDfsClient {

    //上传和下载和删除:
    @RequestMapping(value = "/common/upload",method = RequestMethod.POST)
    AjaxResult upload(@RequestBody MultipartFile file);

    //下载:页面直接使用http://ip/groupname/filename

    //删除:
    @RequestMapping(value = "/common/delete",method = RequestMethod.GET)
    AjaxResult delete(@RequestParam("filePath") String filePath);
}    

(3)还是在同一模块中创建个托底类。FastDfsFall

@Component
public class FastDfsFall implements  FastDfsClient{

    @Override
    public AjaxResult upload(MultipartFile file) {
        return AjaxResult.me().setSuccess(false).setMsg("亲,现在我们的服务很忙,亲稍后在试哦!!!!");
    }

    @Override
    public AjaxResult delete(String filePath) {
        return AjaxResult.me().setSuccess(false).setMsg("亲,现在我们的服务很忙,亲稍后在试哦!!!!");
    }
}

(4)然后在公共服务模块aigou_common_service_6699子模块中暴露接口。FastDfsController

@RestController
@RequestMapping("/common")
public class FastDfsController implements FastDfsClient {

    @RequestMapping(value = "/upload",method = RequestMethod.POST)
    @Override
    public AjaxResult upload(@RequestBody MultipartFile file) {
        try {
            byte[] bytes = file.getBytes();
            //获取原始名:
            String originalFilename = file.getOriginalFilename();
            //获取后缀名:
            String extName = FilenameUtils.getExtension(originalFilename);
            // "/"+fileIds[0]+"/"+fileIds[1];
            String groupNameAndFileName = FastDfsApiOpr.upload(bytes, extName);
            return AjaxResult.me().setSuccess(true).setMsg("亲,文件上传成功!").setObject(groupNameAndFileName);
        } catch (IOException e) {
            e.printStackTrace();
            return AjaxResult.me().setSuccess(false).setMsg("亲,文件上传失败!"+e.getMessage());
        }
    }

    @RequestMapping(value = "/delete",method = RequestMethod.GET)
    @Override
    public AjaxResult delete(@RequestParam("filePath") String filePath) {
        // filePath:   http://ip/groupName/fileName
        //    /groupName/fileName   groupName/fileName
        String filePath1  =filePath.substring(1);
        String  groupName= filePath1.substring(0, filePath1.indexOf("/"));
        String fileName=filePath1.substring(filePath1.indexOf("/")+1);
        int delete = FastDfsApiOpr.delete(groupName, fileName);
        if(delete==0){
            return AjaxResult.me().setSuccess(true).setMsg("删除成功!!");
        }else{
            return AjaxResult.me().setSuccess(false).setMsg("删除失败!!");
        }
    }
    
//拿到的图片存储位置是:组名+路径  用string类型的方法将两者分开来
    public static void main(String[] args) {
        String filePath="/group1/M00/00/01/rBAHy1zYO26AEwFyAAB7VaQUqSY146.png";
       //  group1
       //  M00/00/01/rBAHy1zYLluAMw2BAC7Mdh1oFjs624.avi
        String groupName="";

        // filePath.indexOf("0"):第一个字符串出现的索引:从0开始
        // groupName.substring(0, 2):ab  [)==>左闭右开
        // group1/M00/00/01/rBAHy1zYO26AEwFyAAB7VaQUqSY146.png:只有一个参数的时候:从这个开始截取到最后:filePath.substring(1)
        String filePath1  =filePath.substring(1);//   group1/M00/00/01/rBAHy1zYO26AEwFyAAB7VaQUqSY146.png
        // group1
        groupName= filePath1.substring(0, filePath1.indexOf("/"));
        String fileName=filePath1.substring(filePath1.indexOf("/")+1);
    }
}

3、在公共服务模块aigou_common_service_6699子模块中创建工具类。FastDfsApiOpr

public class FastDfsApiOpr {

    public static String CONF_FILENAME  = FastDfsApiOpr.class.getResource("/fdfs_client.conf").getFile();

    /**
     * 上传文件
     * @param file
     * @param extName
     * @return
     */
    public static  String upload(byte[] file,String extName) {

        try {
            // 1、加载配置文件,配置文件中的内容就是 tracker 服务的地址。
            ClientGlobal.init(CONF_FILENAME);
            // 2、创建一个 TrackerClient 对象。直接 new 一个。
            TrackerClient tracker = new TrackerClient();
            // 3、使用 TrackerClient 对象创建连接,获得一个 TrackerServer 对象。
            TrackerServer trackerServer = tracker.getConnection();
            // 4、创建一个 StorageServer 的引用,值为 null
            StorageServer storageServer = null;
            // 5、创建一个 StorageClient 对象,需要两个参数 TrackerServer 对象、StorageServer 的引用
            StorageClient storageClient = new StorageClient(trackerServer, storageServer);
            NameValuePair nvp [] = new NameValuePair[]{
                    new NameValuePair("age", "18"),
                    new NameValuePair("sex", "male")
            };
            // 6、使用 StorageClient 对象上传图片。返回数组。包含组名和图片的路径。
            String fileIds[] = storageClient.upload_file(file,extName,nvp);
            System.out.println(fileIds.length);
            System.out.println("组名:" + fileIds[0]);
            System.out.println("路径: " + fileIds[1]);
            return  "/"+fileIds[0]+"/"+fileIds[1];
        } catch (Exception e) {
            e.printStackTrace();
            return  null;
        }
    }
	/**
     * 下载文件
     * @param groupName
     * @param fileName
     * @return
     */
    public static byte[] download(String groupName,String fileName) {
        try {

            ClientGlobal.init(CONF_FILENAME);

            TrackerClient tracker = new TrackerClient();
            TrackerServer trackerServer = tracker.getConnection();
            StorageServer storageServer = null;

            StorageClient storageClient = new StorageClient(trackerServer, storageServer);
            byte[] b = storageClient.download_file(groupName, fileName);
            return  b;
        } catch (Exception e) {
            e.printStackTrace();
            return  null;
        }
    }
    /**
     * 删除文件
     * @param groupName
     * @param fileName
     */
    public static int delete(String groupName,String fileName){
        try {
            ClientGlobal.init(CONF_FILENAME);

            TrackerClient tracker = new TrackerClient();
            TrackerServer trackerServer = tracker.getConnection();
            StorageServer storageServer = null;

            StorageClient storageClient = new StorageClient(trackerServer,
                    storageServer);
            int i = storageClient.delete_file(groupName,fileName);
            System.out.println( i==0 ? "删除成功" : "删除失败:"+i);
            return i;
        } catch (Exception e) {
            e.printStackTrace();
            throw  new RuntimeException("删除异常,"+e.getMessage());
        }
    }
}

4、然后在resources资源文件中创建个fdfs_client.conf的IP配置文件

springclod_06_fastdfs图片统一处理_第5张图片

5、进行swagger接口管理和网关配置

(1)在公共服务子模块aigou_common_service_6699的pom.xml中引入swagger依赖




    io.springfox
    springfox-swagger2
    2.9.2



    io.springfox
    springfox-swagger-ui
    2.9.2

6、并在公共服务子模块aigou_common_service_6699中创建个config包,创建swagger的配置

注意:swagger要扫描controller层的包

@Configuration
@EnableSwagger2
public class Swagger2 {
 
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("cn.itsource.aigou.controller"))
                //包:就是自己接口的包路径
                .paths(PathSelectors.any())
                .build();
    }


    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("商品系统api")//名字
                .description("商品系统接口文档说明")//额外藐视
                .contact(new Contact("wbtest", "", "[email protected]"))
                .version("1.0")// 版本
                .build();
    }
}

7、在网关模块aigou_zuul_server_9527中更改部分

(1)在配置中增加个基础模块。

springclod_06_fastdfs图片统一处理_第6张图片

(2)在资源文件resources的YAML配置文件中增加个和配置中一样的zuul规则

是公共服务模块aigou_common_service中的YAMLname配置

springclod_06_fastdfs图片统一处理_第7张图片

8、完成前台页面的图片上传功能

(1)elementUi的文件上传组件格式

springclod_06_fastdfs图片统一处理_第8张图片

(2)测试图片上传

springclod_06_fastdfs图片统一处理_第9张图片

(3)将上传图片的地址保存到数据库中,和删除操作

springclod_06_fastdfs图片统一处理_第10张图片

你可能感兴趣的:(springcloud微服务)