一、圖片存儲介紹
在實際開發中,我們會有很多處理不同功能的服務器。例如:
應用服務器:負責部署我們的應用
數據庫服務器:運行我們的數據庫
文件服務器:負責存儲用戶上傳文件的服務器
分服務器處理的目的是讓服務器各司其職,從而提高我們項目的運行效率。
常見的圖片存儲方案:
方案一:使用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);
}