SAAS-HRM-day4

图片统一处理

  1. 为什么要统一处理

微服务中服务集群后,文件夹资源不能共享

解决方案:分布式文件系统

分布式文件系统:多个文件系统通过管理软件进行管理,得到分布式文件系统.

好处:

  1. 海量存储
  2. 高可用

方案选择

方案1:租用别人已经搭建好了的.

    阿里云对象存储(收费),七牛云(10G内免费)

     好处:方便,小量数据可以

     坏处:大量数据时,要花很多钱.

方案2:自己搭建

    hdfs(hadoop),FastDfs(国产,小文件)....

我们这里使用Fastdfs

Fastdfs介绍

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

FastDFS 架构包括 Tracker server 和 Storage server。

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

 

具体实现步骤;

  1. 搭建fastDfs文件系统
  2. 上传图片
  3. 回显图片

上传和下载流程

 

 

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

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

 

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

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

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

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

文件。

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

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

下载

 

 Fastdfs搭建-一个运维

 代码操作fastdfs-入门

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

(1)pom.xml中引入

<!-- https://mvnrepository.com/artifact/cn.bestwu/fastdfs-client-java -->
<dependency>
    <groupId>cn.bestwu</groupId>
    <artifactId>fastdfs-client-java</artifactId>
    <version>1.27</version>
</dependency>

(2)添加配置文件fdfs_client.conf

tracker_server=122.51.119.246:22122

 (3)创建java类,main方法代码如下:

// 1、加载配置文件,配置文件中的内容就是 tracker 服务的地址。
		ClientGlobal.init("D:/maven_work/fastDFS-demo/src/fdfs_client.conf");
		// 2、创建一个 TrackerClient 对象。直接 new 一个。
		TrackerClient trackerClient = new TrackerClient();
		// 3、使用 TrackerClient 对象创建连接,获得一个 TrackerServer 对象。
		TrackerServer trackerServer = trackerClient.getConnection();
		// 4、创建一个 StorageServer 的引用,值为 null
		StorageServer storageServer = null;
		// 5、创建一个 StorageClient 对象,需要两个参数 TrackerServer 对象、StorageServer 的引用
		StorageClient storageClient = new StorageClient(trackerServer, storageServer);
		// 6、使用 StorageClient 对象上传图片。
		//扩展名不带“.”
		String[] strings = storageClient.upload_file("D:/pic/benchi.jpg", "jpg",
				null);
		// 7、返回数组。包含组名和图片的路径。
		for (String string : strings) {
			System.out.println(string);
		}

 控制台输出如下结果:

group1
M00/00/00/wKgZhVkMP4KAZEy-AAA-tCf93Fo973.jpg

 

在浏览器输入:

http://122.51.119.246/group1/M00/00/00/wKgZhVkMP4KAZEy-AAA-tCf93Fo973.jp

 

后台上传服务

 导入jar

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Eureka 客户端依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!--配置中心支持-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>

配置yml

Bootstrap.yml
spring:
  profiles:
    active: dev
  cloud:
    config:
      name: application-common #github上面名称
      profile: ${spring.profiles.active} #环境 java -jar -D xxx jar
      label: master #分支
      discovery:
        enabled: true #从eureka上面找配置服务
        service-id: hrm-config-server #指定服务名
      #uri: http://127.0.0.1:1299 #配置服务器 单机配置
eureka: #eureka不能放到远程配置中
  client:
    service-url:
      defaultZone: http://localhost:1010/eureka  #告诉服务提供者要把服务注册到哪儿 #单机环境
  instance:
    prefer-ip-address: true #显示客户端真实ip

 配置库 application-common-dev.yml

server:
  port: 2090
spring:
  application:
    name: hrm-common

通过网关访问的配置:

zuul:
  routes:
    sysmanage.serviceId: hrm-sysmanage #这是调用满足条件的服务名,注意要小写
    sysmanage.path: /sysmanage/** #这是所有路径前的通配
    common.serviceId: hrm-common #这是调用满足条件的服务名,注意要小写
    common.path: /common/** #这是所有路径前的通配
    course.serviceId: hrm-course #这是调用满足条件的服务名,注意要小写
    course.path: /course/** #这是所有路径前的通配
  ignored-services: "*" #用*来通配符,忽略从9527端口通过服务名来调用
  prefix: "/services" #这是所有路径的前缀
retryable: true #是否重试

 Swagger

@Configuration
@EnableSwagger2
public class Swagger2 {
 
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                //对外暴露服务的包,以controller的方式暴露,所以就是controller的包.
                .apis(RequestHandlerSelectors.basePackage("com.zhanglin.controller"))
                .paths(PathSelectors.any())
                .build();
    }


    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("公共服务api")
                .description("公共服务接口文档说明")
                .contact(new Contact("zltest", "", "zl@itsource.cn"))
                .version("1.0")
                .build();
    }

}

入口类

@SpringBootApplication
@EnableEurekaClient
public class CommonService2090Application {

	
	public static void main(String[] args) {
		
		SpringApplication.run(CommonService2090Application .class, args);
	}
}

 

测试

 

http://localhost:1030/swagger-ui.html

实现fastdfs服务(配置参照上面)

@RestController
public class FastDfsController {

    @RequestMapping(value = "/upload",method = RequestMethod.POST)
    public AjaxResult upload(@RequestParam(value = "file",required = true)MultipartFile file){
        try {
            System.out.println(file.getOriginalFilename() + ":" + file.getSize());
            String originalFilename = file.getOriginalFilename();
            // xxx.jpg
            String extName = originalFilename.substring(originalFilename.lastIndexOf(".")+1);
            System.out.println(extName);
            String filePath =  FastDfsApiOpr.upload(file.getBytes(), extName);
            return AjaxResult.me().setResultObj(filePath);
        } catch (IOException e) {
            e.printStackTrace();
            return AjaxResult.me().setSuccess(false).setMessage("上传失败!"+e.getMessage());
        }
    }


    // /goup1/xxxxx/yyyy
    @RequestMapping(value = "/del",method = RequestMethod.DELETE)
    public AjaxResult upload(@RequestParam(value = "filePath",required = true)String filePath){
        String pathTmp = filePath.substring(1); // goup1/xxxxx/yyyy
        String groupName =  pathTmp.substring(0, pathTmp.indexOf("/")); //goup1
        String remotePath = pathTmp.substring(pathTmp.indexOf("/"));// /xxxxx/yyyy
        FastDfsApiOpr.delete(groupName, remotePath);
        return  AjaxResult.me();
    }
}

前端文件上传

<el-upload
      class="upload-demo"
      action="http://127.0.0.1:9527/services/common/upload"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :file-list="fileList2"
      :on-success="handleSuccess"
      list-type="picture"
       >

   <el-button size="small" type="primary">点击上传</el-button>
   <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>

 缩略图数据:

 

课程中心功能分析

课程中心-后台服务搭建

创建模块

父工程:hrm_course_parent

子工程:

hrm_course_common:    domain,query,client feign接口(内部服务调用)

hrm_course_service: controller,service,mapper

common:

导入pom

<dependencies>
        <!--不能直接依赖starter,有自动配置,而消费者是不需要额。-->
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
       
        <dependency>
            <groupId>cn.itsource.agiou</groupId>
            <artifactId>basic_util</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

Service:

<dependencies>
       
        <!--所有provider公共依賴-->
        <dependency>
            <groupId>cn.itsource.hrm</groupId>
            <artifactId>course_interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
 <!-- Eureka 客户端依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

       <!--配置中心支持-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        
    </dependencies>

配置yml

 

Bootstrap.yml
spring:
  profiles:
    active: dev
  cloud:
    config:
      name: application-common #github上面名称
      profile: ${spring.profiles.active} #环境 java -jar -D xxx jar
      label: master #分支
      discovery:
        enabled: true #从eureka上面找配置服务
        service-id: hrm-config-server #指定服务名
      #uri: http://127.0.0.1:1299 #配置服务器 单机配置
eureka: #eureka不能放到远程配置中
  client:
    service-url:
      defaultZone: http://localhost:1010/eureka  #告诉服务提供者要把服务注册到哪儿 #单机环境
  instance:
    prefer-ip-address: true #显示客户端真实ip

 配置库 application-common-dev.yml

server:
  port: 2090
spring:
  application:
    name: hrm-common

配置网关,swagger,入口类

课程中心

课程类型树

树形数据无限极获取

controller

@GetMapping("/treeData")
    public List<CourseType> treeData() {
        return courseTypeService.treeData(0L);
    }

 service:

/**
     * 获取多级菜单
     * @param pid
     * @return
     */
    List<CourseType> treeData(long pid);
@Service
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {

    @Autowired
    private CourseTypeMapper courseTypeMapper;
    @Override
    public List<CourseType> treeData(long pid) {
        return treeDataRecursion(pid);
    }

    //递归思想
    private List<CourseType> treeDataRecursion(long pid) {
        List<CourseType> children = courseTypeMapper.selectList(new EntityWrapper<CourseType>().eq("pid", pid));
        //返回条件
        if (children==null || children.size()<1){
            return null;
        }
        for (CourseType child : children) {
            //自己调用自己
            List<CourseType> cTmp = treeDataRecursion(child.getId());
            child.setChildren(cTmp);
        }

        return children;
    }

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值