1. redis相关配置
1.1 spring整合redis
spring-redis.xml 配置了Jedis相关的配置
什么是Jedis?
——Jedis用Java语言连接redis服务,并提供对应的操作API,方便我们把程序中的数据交给redis管理,同时,还可以取出redis中的数据到我们的程序中
maven坐标
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</version></dependency>
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsdhttp://www.springframework.org/schema/contexthttp://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>
在后台的使用
@Autowiredprivate JedisPool jedisPool;//将上传图片名称存入Redis,基于Redis的Set集合存储 RedisConstant.SETMEAL_PIC_RESOURCES表示key值jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_RESOURCES,fileName);
1.2 Jedis简易工具类开发
基于连接池获取连接
JedisPool:Jedis提供的连接池技术 poolConfig:连接池配置对象 host:redis服务地址 port:redis服务端口号
JedisUtils.java
package com.itheima.util;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.JedisPoolConfig;import java.util.ResourceBundle;public class JedisUtils {private static int maxTotal;private static int maxIdel;private static String host;private static int port;private static JedisPoolConfig jpc;private static JedisPool jp;static {ResourceBundle bundle = ResourceBundle.getBundle("redis");maxTotal = Integer.parseInt(bundle.getString("redis.maxTotal"));maxIdel = Integer.parseInt(bundle.getString("redis.maxIdel"));host = bundle.getString("redis.host");port = Integer.parseInt(bundle.getString("redis.port"));//Jedis连接池配置jpc = new JedisPoolConfig();jpc.setMaxTotal(maxTotal);jpc.setMaxIdle(maxIdel);jp = new JedisPool(jpc,host,port);}public static Jedis getJedis(){return jp.getResource();}}
redis.propeties
redis.maxTotal=50redis.maxIdel=10redis.host=192.168.40.130redis.port=6379
1.3 Redis的相关API
2. Redis应用场景
2.1 定时清理垃圾图片
使用到的技术点:
Redis(统计出哪些是垃圾图片)+Qiniuyun(图片存储服务器)+Quartz(定时清理七牛云上的垃圾图片)
基于Quartz定时任务,通过计算redis两个集合的差值找出所有的垃圾图片,就可以将垃圾图片清理掉。

点击+号上传图片,图片存储到七牛云服务器上,但如果用户只上传了图片而没有最终保存套餐信息到我们的数据库,这时我们上传的图片就变为了垃圾图片。对于这些垃圾图片我们需要定时清理来释放磁盘空间。这就需要我们能够区分出来哪些是垃圾图片,哪些不是垃圾图片。如何实现呢?
方案就是利用redis来保存图片名称,具体做法为:
1、当用户上传图片后,将图片名称保存到redis的一个Set集合中,例如集合名称为setmealPicResources(在服务消费方操作)
2、当用户添加套餐后,将图片名称保存到redis的另一个Set集合中,例如集合名称为setmealPicDbResources(在服务提供方操作)
3、计算setmealPicResources集合与setmealPicDbResources集合的差值,结果就是垃圾图片的名称集合,清理这些图片即可

创建ClearImgJob定时任务类
package com.itheima.jobs;import com.itheima.constant.RedisConstant;import com.itheima.utils.QiniuUtils;import org.springframework.beans.factory.annotation.Autowired;import redis.clients.jedis.JedisPool;import java.util.Set;/*** 自定义Job,实现定时清理垃圾图片*/public class ClearImgJob {@Autowiredprivate JedisPool jedisPool;public void clearImg(){//根据Redis中保存的两个set集合进行差值计算,获得垃圾图片名称集合Set<String> set =jedisPool.getResource().sdiff(RedisConstant.SETMEAL_PIC_RESOURCES,RedisConstant.SETMEAL_PIC_DB_RESOURCES);if(set != null){for (String picName : set) {//删除七牛云服务器上的图片QiniuUtils.deleteFileFromQiniu(picName);//从Redis集合中删除图片名称jedisPool.getResource().srem(RedisConstant.SETMEAL_PIC_RESOURCES,picName);}}}}
2.2 利用redis存放手机验证码
redis存放手机验证码需要注意:
- 验证码一般是有时效性的,需要设置过期时间
- 在项目中会有多个场景需要使用到验证码(比如手机快速登录、预约体检、找回密码),因此需要使用手机号+场景码作为redis的key,防止出现验证码替换问题
为什么需要保存验证码到redis中?**
因为验证码一般是有时效性的,所以保存在数据库中不合适。如果把验证码存在session中,会对服务器产生压力;而存储在redis中,由于它是另一台服务器,不会造成压力
2.2.1 实际应用
public class RedisConstant {//不同的场景码public static final String SENDTYPE_ORDER = "001";//用于缓存体检预约时发送的验证码public static final String SENDTYPE_LOGIN = "002";//用于缓存手机号快速登录时发送的验证码public static final String SENDTYPE_GETPWD = "003";//用于缓存找回密码时发送的验证码}
Controller层
@RestController@RequestMapping("/validateCode")public class ValidateCodeController {@Autowiredprivate JedisPool jedisPool;@RequestMapping("/send4Order")public Result send4Order(String telephone){Integer code = ValidateCodeUtils.generateValidateCode(4);try {SMSUtils.sendShortMessage(SMSUtils.VALIDATE_CODE,telephone, String.valueOf(code));} catch (ClientException e) {e.printStackTrace();return new Result(false, MessageConstant.SEND_VALIDATECODE_FAIL);}System.out.println("发送的手机验证码为:" + code);//将生成的验证码缓存到redis//考虑到多个场景下都需要用到验证码 因此使用手机号+场景码作为redis的key值 防止出现验证码替换问题jedisPool.getResource().setex(telephone+ RedisConstant.SENDTYPE_ORDER,5*60,String.valueOf(code));//验证码发送成功return new Result(true, MessageConstant.SEND_VALIDATECODE_SUCCESS);}}


