1. redis相关配置

1.1 spring整合redis

spring-redis.xml 配置了Jedis相关的配置
什么是Jedis?
——Jedis用Java语言连接redis服务,并提供对应的操作API,方便我们把程序中的数据交给redis管理,同时,还可以取出redis中的数据到我们的程序中
maven坐标

  1. <dependency>
  2. <groupId>redis.clients</groupId>
  3. <artifactId>jedis</artifactId>
  4. <version>2.9.0</version>
  5. </dependency>
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:p="http://www.springframework.org/schema/p"
  5. xmlns:context="http://www.springframework.org/schema/context"
  6. xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
  7. xmlns:mvc="http://www.springframework.org/schema/mvc"
  8. xsi:schemaLocation="http://www.springframework.org/schema/beans
  9. http://www.springframework.org/schema/beans/spring-beans.xsd
  10. http://www.springframework.org/schema/mvc
  11. http://www.springframework.org/schema/mvc/spring-mvc.xsd
  12. http://code.alibabatech.com/schema/dubbo
  13. http://code.alibabatech.com/schema/dubbo/dubbo.xsd
  14. http://www.springframework.org/schema/context
  15. http://www.springframework.org/schema/context/spring-context.xsd">
  16. <!--Jedis连接池的相关配置-->
  17. <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
  18. <property name="maxTotal">
  19. <value>200</value>
  20. </property>
  21. <property name="maxIdle">
  22. <value>50</value>
  23. </property>
  24. <property name="testOnBorrow" value="true"/>
  25. <property name="testOnReturn" value="true"/>
  26. </bean>
  27. <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
  28. <constructor-arg name="poolConfig" ref="jedisPoolConfig" />
  29. <constructor-arg name="host" value="127.0.0.1" />
  30. <constructor-arg name="port" value="6379" type="int" />
  31. <constructor-arg name="timeout" value="30000" type="int" />
  32. </bean>
  33. </beans>

在后台的使用

  1. @Autowired
  2. private JedisPool jedisPool;
  3. //将上传图片名称存入Redis,基于Redis的Set集合存储 RedisConstant.SETMEAL_PIC_RESOURCES表示key值
  4. jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_RESOURCES,fileName);

1.2 Jedis简易工具类开发

基于连接池获取连接

JedisPool:Jedis提供的连接池技术 poolConfig:连接池配置对象 host:redis服务地址 port:redis服务端口号

JedisUtils.java

  1. package com.itheima.util;
  2. import redis.clients.jedis.Jedis;
  3. import redis.clients.jedis.JedisPool;
  4. import redis.clients.jedis.JedisPoolConfig;
  5. import java.util.ResourceBundle;
  6. public class JedisUtils {
  7. private static int maxTotal;
  8. private static int maxIdel;
  9. private static String host;
  10. private static int port;
  11. private static JedisPoolConfig jpc;
  12. private static JedisPool jp;
  13. static {
  14. ResourceBundle bundle = ResourceBundle.getBundle("redis");
  15. maxTotal = Integer.parseInt(bundle.getString("redis.maxTotal"));
  16. maxIdel = Integer.parseInt(bundle.getString("redis.maxIdel"));
  17. host = bundle.getString("redis.host");
  18. port = Integer.parseInt(bundle.getString("redis.port"));
  19. //Jedis连接池配置
  20. jpc = new JedisPoolConfig();
  21. jpc.setMaxTotal(maxTotal);
  22. jpc.setMaxIdle(maxIdel);
  23. jp = new JedisPool(jpc,host,port);
  24. }
  25. public static Jedis getJedis(){
  26. return jp.getResource();
  27. }
  28. }

redis.propeties

  1. redis.maxTotal=50
  2. redis.maxIdel=10
  3. redis.host=192.168.40.130
  4. redis.port=6379

1.3 Redis的相关APIimage.png

image.png
image.png

2. Redis应用场景

2.1 定时清理垃圾图片

使用到的技术点:
Redis(统计出哪些是垃圾图片)+Qiniuyun(图片存储服务器)+Quartz(定时清理七牛云上的垃圾图片)
基于Quartz定时任务,通过计算redis两个集合的差值找出所有的垃圾图片,就可以将垃圾图片清理掉。
image.pngimage.png
点击+号上传图片,图片存储到七牛云服务器上,但如果用户只上传了图片而没有最终保存套餐信息到我们的数据库,这时我们上传的图片就变为了垃圾图片。对于这些垃圾图片我们需要定时清理来释放磁盘空间。这就需要我们能够区分出来哪些是垃圾图片,哪些不是垃圾图片。如何实现呢?
方案就是利用redis来保存图片名称,具体做法为:

1、当用户上传图片后,将图片名称保存到redis的一个Set集合中,例如集合名称为setmealPicResources(在服务消费方操作)

2、当用户添加套餐后,将图片名称保存到redis的另一个Set集合中,例如集合名称为setmealPicDbResources(在服务提供方操作)

3、计算setmealPicResources集合与setmealPicDbResources集合的差值,结果就是垃圾图片的名称集合,清理这些图片即可

优化图片上传及定时清理垃圾图片.png
创建ClearImgJob定时任务类

  1. package com.itheima.jobs;
  2. import com.itheima.constant.RedisConstant;
  3. import com.itheima.utils.QiniuUtils;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import redis.clients.jedis.JedisPool;
  6. import java.util.Set;
  7. /**
  8. * 自定义Job,实现定时清理垃圾图片
  9. */
  10. public class ClearImgJob {
  11. @Autowired
  12. private JedisPool jedisPool;
  13. public void clearImg(){
  14. //根据Redis中保存的两个set集合进行差值计算,获得垃圾图片名称集合
  15. Set<String> set =
  16. jedisPool.getResource().sdiff(RedisConstant.SETMEAL_PIC_RESOURCES,
  17. RedisConstant.SETMEAL_PIC_DB_RESOURCES);
  18. if(set != null){
  19. for (String picName : set) {
  20. //删除七牛云服务器上的图片
  21. QiniuUtils.deleteFileFromQiniu(picName);
  22. //从Redis集合中删除图片名称
  23. jedisPool.getResource().
  24. srem(RedisConstant.SETMEAL_PIC_RESOURCES,picName);
  25. }
  26. }
  27. }
  28. }

2.2 利用redis存放手机验证码

redis存放手机验证码需要注意:

  • 验证码一般是有时效性的,需要设置过期时间
  • 在项目中会有多个场景需要使用到验证码(比如手机快速登录、预约体检、找回密码),因此需要使用手机号+场景码作为redis的key,防止出现验证码替换问题


为什么需要保存验证码到redis中?**
因为验证码一般是有时效性的,所以保存在数据库中不合适。如果把验证码存在session中,会对服务器产生压力;而存储在redis中,由于它是另一台服务器,不会造成压力

2.2.1 实际应用

  1. public class RedisConstant {
  2. //不同的场景码
  3. public static final String SENDTYPE_ORDER = "001";//用于缓存体检预约时发送的验证码
  4. public static final String SENDTYPE_LOGIN = "002";//用于缓存手机号快速登录时发送的验证码
  5. public static final String SENDTYPE_GETPWD = "003";//用于缓存找回密码时发送的验证码
  6. }

Controller层

  1. @RestController
  2. @RequestMapping("/validateCode")
  3. public class ValidateCodeController {
  4. @Autowired
  5. private JedisPool jedisPool;
  6. @RequestMapping("/send4Order")
  7. public Result send4Order(String telephone){
  8. Integer code = ValidateCodeUtils.generateValidateCode(4);
  9. try {
  10. SMSUtils.sendShortMessage(SMSUtils.VALIDATE_CODE,telephone, String.valueOf(code));
  11. } catch (ClientException e) {
  12. e.printStackTrace();
  13. return new Result(false, MessageConstant.SEND_VALIDATECODE_FAIL);
  14. }
  15. System.out.println("发送的手机验证码为:" + code);
  16. //将生成的验证码缓存到redis
  17. //考虑到多个场景下都需要用到验证码 因此使用手机号+场景码作为redis的key值 防止出现验证码替换问题
  18. jedisPool.getResource().setex(telephone+ RedisConstant.SENDTYPE_ORDER,5*60,String.valueOf(code));
  19. //验证码发送成功
  20. return new Result(true, MessageConstant.SEND_VALIDATECODE_SUCCESS);
  21. }
  22. }

image.png