项目功能-图片清理(上)
一、图片存储介绍
在实际开发中,我们会有很多处理不同功能的服务器。例如:
应用服务器:负责部署我们的应用
数据库服务器:运行我们的数据库
文件服务器:负责存储用户上传文件的服务器
分服务器处理的目的是让服务器各司其职,从而提高我们项目的运行效率。
常见的图片存储方案:
方案一:使用nginx搭建图片服务器
方案二:使用开源的分布式文件存储系统,例如Fastdfs、HDFS等
方案三:使用云存储,例如阿里云、七牛云等
二、垃圾图片问题分析
我们已经完成了文件上传。但是这个过程存在一个问题,就是如果用户只上传了图片而没有最终保存套餐信息到我们的数据库,这时我们上传的图片就变为了垃圾图片。对于这些垃圾图片我们需要定时清理来释放磁盘空间。这就需要我们能够区分出来哪些是垃圾图片,哪些不是垃圾图片。如何实现呢?
方案就是利用redis来保存图片名称,具体做法为:
步骤1、当用户上传图片后,将图片名称保存到redis的一个Set集合中,例如集合名称为setmealPicResources
步骤2、当用户添加套餐后,将图片名称保存到redis的另一个Set集合中,例如集合名称为setmealPicDbResources
步骤3、计算setmealPicResources集合与setmealPicDbResources集合的差值,结果就是垃圾图片的名称集合,清理这些图片即可
本文章我们先来完成前面2个步骤,第3个环节(清理图片环节)我们会通过定时任务来实现。清理垃圾图片并不需要实时清理,一般情况下,一个月两个月清理一次,就可以。我们需要使用到定时任务。
三、垃圾图片清理的实现步骤
实现步骤:
步骤一:在health_backend项目中提供Spring配置文件spring-redis.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--Jedis连接池的相关配置--><bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"><property name="maxTotal"><value>200</value></property><property name="maxIdle"><value>50</value></property><property name="testOnBorrow" value="true"/><property name="testOnReturn" value="true"/></bean><bean id="jedisPool" class="redis.clients.jedis.JedisPool"><constructor-arg name="poolConfig" ref="jedisPoolConfig" /><constructor-arg name="host" value="127.0.0.1" /><constructor-arg name="port" value="6379" type="int" /><constructor-arg name="timeout" value="30000" type="int" /></bean>
</beans>
步骤二:在health_common工程中提供Redis常量类
package com.it.constant;
public class RedisConstant {//套餐图片所有图片名称public static final String SETMEAL_PIC_RESOURCES = "setmealPicResources";//套餐图片保存在数据库中的图片名称public static final String SETMEAL_PIC_DB_RESOURCES = "setmealPicDbResources";
}
步骤三:完善SetmealController,在文件上传成功后将图片名称保存到redis集合中
@Autowired
private JedisPool jedisPool;
//图片上传
@RequestMapping("/upload")
public Result upload(@RequestParam("imgFile")MultipartFile imgFile){try{//获取原始文件名String originalFilename = imgFile.getOriginalFilename();int lastIndexOf = originalFilename.lastIndexOf(".");//获取文件后缀String suffix = originalFilename.substring(lastIndexOf - 1);//使用UUID随机产生文件名称,防止同名文件覆盖String fileName = UUID.randomUUID().toString() + suffix;QiniuUtils.upload2Qiniu(imgFile.getBytes(),fileName);//图片上传成功Result result = new Result(true, MessageConstant.PIC_UPLOAD_SUCCESS);result.setData(fileName);//将上传图片名称存入Redis,基于Redis的Set集合存储jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_RESOURCES,fileName);return result;}catch (Exception e){e.printStackTrace();//图片上传失败return new Result(false,MessageConstant.PIC_UPLOAD_FAIL);}
}
步骤四:在health_service_provider项目中提供Spring配置文件applicationContext-redis.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--Jedis连接池的相关配置--><bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"><property name="maxTotal"><value>200</value></property><property name="maxIdle"><value>50</value></property><property name="testOnBorrow" value="true"/><property name="testOnReturn" value="true"/></bean><bean id="jedisPool" class="redis.clients.jedis.JedisPool"><constructor-arg name="poolConfig" ref="jedisPoolConfig" /><constructor-arg name="host" value="127.0.0.1" /><constructor-arg name="port" value="6379" type="int" /><constructor-arg name="timeout" value="30000" type="int" /></bean>
</beans>
步骤五:完善SetmealServiceImpl服务类,在保存完成套餐信息后将图片名称存储到redis集合中
@Autowired
private JedisPool jedisPool;
//新增套餐
public void add(Setmeal setmeal, Integer[] checkgroupIds) {setmealDao.add(setmeal);if(checkgroupIds != null && checkgroupIds.length > 0){setSetmealAndCheckGroup(setmeal.getId(),checkgroupIds);}savePic2Redis(setmeal.getImg());
}
//将图片名称保存到Redis
private void savePic2Redis(String pic){jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_DB_RESOURCES,pic);
}