SpringBoot中搭建Redis缓存

简介: SpringBoot中搭建Redis缓存 (一)SpringBoot中搭建Redis缓存 这篇文章讲述如何在Springboot中搭建redis,参考了很多大神的文章但是运用在我的项目里却不能发挥出来 ,可能框架原因把,因为是在项目搭建完成后再来搭的redis的。
+关注继续查看

SpringBoot中搭建Redis缓存

(一)SpringBoot中搭建Redis缓存

这篇文章讲述如何在Springboot中搭建redis,参考了很多大神的文章但是运用在我的项目里却不能发挥出来
,可能框架原因把,因为是在项目搭建完成后再来搭的redis的。搭建redis我感觉我这篇文章比较简单、方便、容易维护话不多说进入正题。

1)、以下链接 是如何在window本地搭建redis进行测试http://www.bieryun.com/3206.html

注意:在导入jedis-2.6.2.jar、spring-data-redis-1.4.2.RELEASE.jar  如果你下载的版本太低可能会提示版本有误(解决方法只要重新下一个高版本就行了),我这个版本应该是没错的。之前

spring-data-redis-1.4.2.RELEASE.jar 我是下载1.0.0所以太低了。

2)在Springboot运用redis方法进行缓存操作

第一步:在pom.xml文件中配置redis

[html] view plain copy

  1. <!--redis配置-->
  2. <dependency>
  3.     <groupId>org.springframework.boot</groupId>
  4.     <artifactId>spring-boot-starter-redis</artifactId>  <!-- 可以不需要加入版本号 -->
  5. </dependency>
  6.  <dependency>
  7.         <groupId>redis.clients</groupId>
  8.         <artifactId>jedis</artifactId>
  9.          <version>2.5.2</version>
  10.     </dependency>

第二步:初始化Redis连接池 ,操作redis

CacheKit.java:

[html] view plain copy

  1. package com.zcwl.redis;
  2. import java.util.ArrayList;
  3. import java.util.Date;
  4. import java.util.Iterator;
  5. import java.util.List;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import com.alibaba.fastjson.JSONArray;
  9. import com.alibaba.fastjson.JSONObject;
  10. import redis.clients.jedis.Jedis;
  11. import redis.clients.jedis.JedisPool;
  12. import redis.clients.jedis.JedisPoolConfig;
  13. import redis.clients.jedis.exceptions.JedisConnectionException;
  14. public class CacheKit {
  15.     private static Logger logger = LoggerFactory.getLogger(CacheKit.class);
  16.     private List<JSONObject> resultList;
  17.     private static JedisPool pool;
  18.      /**
  19.      * 初始化Redis连接池
  20.      */
  21.     private static void initializePool() {
  22.         //redisURL 与 redisPort 的配置文件
  23.         JedisPoolConfig config = new JedisPoolConfig();
  24.         //设置最大连接数(100个足够用了,没必要设置太大)
  25.         config.setMaxTotal(100);
  26.         //最大空闲连接数
  27.         config.setMaxIdle(10);
  28.         //获取Jedis连接的最大等待时间(50秒)
  29.         config.setMaxWaitMillis(50 * 1000);
  30.         //在获取Jedis连接时,自动检验连接是否可用
  31.         config.setTestOnBorrow(true);
  32.         //在将连接放回池中前,自动检验连接是否有效
  33.         config.setTestOnReturn(true);
  34.         //自动测试池中的空闲连接是否都是可用连接
  35.         config.setTestWhileIdle(true);
  36.         //创建连接池
  37.         //pool = new JedisPool(config, "120.88.166.244",6379);  //连接阿里云服务器上面的缓存(如果本地在使用地址,本地运行将会把本地缓存数据同步在线上缓存中)
  38.         pool = new JedisPool(config, "127.0.0.1",6379); //本地缓存(更新需要将这个注释起来,解开上面地址)
  39.     }
  40.     /**
  41.      * 多线程环境同步初始化(保证项目中有且仅有一个连接池)
  42.      */
  43.     private static synchronized void poolInit() {
  44.         if (null == pool) {
  45.             initializePool();
  46.         }
  47.     }
  48.     /**
  49.      * 获取Jedis实例
  50.      */
  51.     private static Jedis getJedis() {
  52.         if (null == pool) {
  53.             poolInit();
  54.         }
  55.         int timeoutCount = 0;
  56.         while (true) {
  57.             try {
  58.                 if (null != pool) {
  59.                     return pool.getResource();
  60.                 }
  61.             } catch (Exception e) {
  62.                 if (e instanceof JedisConnectionException) {
  63.                     timeoutCount++;
  64.                     logger.warn("getJedis timeoutCount={}", timeoutCount);
  65.                     if (timeoutCount > 3) {
  66.                         break;
  67.                     }
  68.                 } else {
  69.                    /* logger.warn("jedisInfo ... NumActive=" + pool.getResource().get("")
  70.                             + ", NumIdle=" + pool.getNumIdle()
  71.                             + ", NumWaiters=" + pool.getNumWaiters()
  72.                             + ", isClosed=" + pool.isClosed());  */
  73.                     logger.warn(pool.getResource()+"//"+pool);
  74.                     logger.error("GetJedis error,", e);
  75.                     break;
  76.                 }
  77.             }
  78.             break;
  79.         }
  80.         return null;
  81.     }
  82.     /**
  83.      * 释放Jedis资源
  84.      *
  85.      * @param jedis
  86.      */
  87.     private static void returnResource(Jedis jedis) {
  88.         if (null != jedis) {
  89.             pool.returnResourceObject(jedis);
  90.         }
  91.     }
  92.     /**
  93.      * 绝对获取方法(保证一定能够使用可用的连接获取到 目标数据)
  94.      * Jedis连接使用后放回
  95.      * @param key
  96.      * @return
  97.      */
  98.     private String safeGet(String key) {
  99.         Jedis jedis = getJedis();
  100.         while (true) {
  101.             if (null != jedis) {
  102.                 break;
  103.             } else {
  104.                 jedis = getJedis();
  105.             }
  106.         }
  107.         String value = jedis.get(key);
  108.         returnResource(jedis);
  109.         return value;
  110.     }
  111.     /**
  112.      * 绝对设置方法(保证一定能够使用可用的链接设置 数据)
  113.      * Jedis连接使用后返回连接池
  114.      * @param key
  115.      * @param time
  116.      * @param value
  117.      */
  118.     public void safeSet(String key, int time, String value) {
  119.         Jedis jedis = getJedis();
  120.         while (true) {
  121.             if (null != jedis) {
  122.                 break;
  123.             } else {
  124.                 jedis = getJedis();
  125.             }
  126.         }
  127.         jedis.setex(key, time, value);
  128.         returnResource(jedis);
  129.     }
  130.     /**
  131.      * 绝对删除方法(保证删除绝对有效)
  132.      * Jedis连接使用后返回连接池</span>
  133.      * @param key
  134.      */
  135.     private void safeDel(String key) {
  136.         Jedis jedis = getJedis();
  137.         while (true) {
  138.             if (null != jedis) {
  139.                 break;
  140.             } else {
  141.                 jedis = getJedis();
  142.             }
  143.         }
  144.         jedis.del(key);
  145.         returnResource(jedis);
  146.     }
  147.     /**
  148.      * 清除所有缓存
  149.      */
  150.     private static void clearCache(){
  151.         CacheKit kit = new CacheKit();
  152.         Jedis jedis = getJedis();
  153.         while (true) {
  154.             if (null != jedis) {
  155.                 break;
  156.             } else {
  157.                 jedis = getJedis();
  158.             }
  159.         }

[html] view plain copy

  1.        //PS:redis默认有一些key已经存在里面,不能删除,所以后面在添加key的时候用一个统一的标识符这样将自己添加的删除
  2.         Iterator it = jedis.keys("redis*").iterator();  //带*号清除所有,如果写有前缀就匹配出来sy*
  3.         while (it.hasNext()) {
  4.             String key = (String) it.next();
  5.             kit.delByCache(key);    //删除key
  6.             logger.info(new Date()+":将redis缓存"+key+"值删除成功!");
  7.         }
  8.         returnResource(jedis);
  9.     }
  10.     /**自定义的一些 get set del 方法,方便使用  在其他地方直接调用**/
  11.     public JSONObject getByCache(String key) {
  12.         String result = safeGet(key);
  13.         if (result != null) {
  14.             return (JSONObject) JSONObject.parse(result);
  15.         }
  16.         return null;
  17.     }
  18.     public String getByCacheToString(String key) {
  19.         String result = safeGet(key);
  20.         if (result != null) {
  21.             return result;
  22.         }
  23.         return null;
  24.     }
  25.     public List<JSONObject> getArrayByCache(String key) {
  26.         String result = safeGet(key);
  27.         if (result != null) {
  28.             resultList = JSONArray.parseArray(result, JSONObject.class);
  29.             return resultList;
  30.         }
  31.         return null;
  32.     }
  33.     public JSONArray getJSONArrayByCache(String key) {
  34.         String result = safeGet(key);
  35.         if (result != null) {
  36.             return JSONArray.parseArray(result);
  37.         }
  38.         return null;
  39.     }
  40.     public void setByCache(String key, String s) {
  41.         safeSet(key, 86400, s);
  42.     }
  43.     public void setByCacheOneHour(String key, String s) {
  44.         safeSet(key, 3600, s);
  45.     }
  46.     public void setByCacheOneHour(String key, List<JSONObject> json) {
  47.         safeSet(key, 86400, JSONObject.toJSONString(json));
  48.         resultList = json;
  49.     }
  50.     public void setByCache(String key, JSONObject json) {
  51.         safeSet(key, 86400, JSONObject.toJSONString(json));
  52.     }
  53.     public void setByCache(String key, List<JSONObject> list) {
  54.         safeSet(key, 86400, JSONObject.toJSONString(list));
  55.         resultList = list;
  56.     }
  57.     public void setByCache(String key, JSONArray array) {
  58.         safeSet(key, 86400, JSONArray.toJSONString(array));
  59.     }
  60.     public void setByCacheCusTime(String key, String s, int time) {
  61.         safeSet(key, time, s);
  62.     }
  63.     public void delByCache(String key) {
  64.         //该方法删除指定的key
  65.         if (null != safeGet(key)) {
  66.             safeDel(key);
  67.         }
  68.     }
  69.     //该方法用来清除所有相关redis的key
  70.     public void delRedisRelevantKey(){
  71.         clearCache();
  72.     }
  73.     public JSONObject toJSON(JSONObject db) {
  74.         return (JSONObject) JSONObject.toJSON(db);
  75.     }
  76.     public List<JSONObject> toJSON(List<JSONObject> list) {
  77.         List<JSONObject> json = new ArrayList<>();
  78.         for (JSONObject aList : list) {
  79.             json.add((JSONObject) JSONObject.toJSON(aList));
  80.         }
  81.         return json;
  82.     }
  83.     public boolean notNull() {
  84.         return resultList != null && resultList.size() > 0;
  85.     }
  86.     public List<JSONObject> getResult() {
  87.         return resultList;
  88.     }
  89.     public static void main(String[] args) {
  90.         //clearCache();  到这里自己去测试一下是否可以
  91.     }
  92. }

之前看过其它大神的文章,都是将缓存地址放到application.properties、还有什么application.yml里面,但是我试过到我这里取不到地址,试过很多方式取不到所以才决定地址放到外面,我个人觉得影响应该不会很大。

里面也写了很多公共方法方便调用管理。如果这里测试没问题那就运用到业务流程存储数据。

RedisUtil.java

这个类用来写redis公共方法

[html] view plain copy

  1. package com.zcwl.redis;
  2. import java.util.ArrayList;
  3. import java.util.Date;
  4. import java.util.List;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import com.zcwl.goods.dto.GoodsBrand;
  8. import net.sf.json.JSONObject;
  9. /**
  10.  * redis缓存公共方法
  11.  * @author Liangth
  12.  */
  13. public class RedisUtil {
  14.     private static Logger log = LoggerFactory.getLogger(RedisUtil.class);
  15.     //redisSyIndexBrand    命名分解  redis(用来清除缓存时候,查找) SY(代表首页比如商城:SC) 后面随机变化
  16.     private static final String index_Brand = "redisSyIndexBrand";      //首页推荐品牌
  17.     private static CacheKit kit = new CacheKit();
  18.     /**
  19.      * 首页推荐品牌
  20.      * start
  21.      */
  22.     //缓存数据
  23.     public void saveIndexBrand(List<GoodsBrand> goodsBrand){
  24.         try {
  25.             List<JSONObject> array = new ArrayList<JSONObject>();
  26.             for (int i = 0; i < goodsBrand.size(); i++) {
  27.                 JSONObject object = new JSONObject();
  28.                 object.put("id", goodsBrand.get(i).getId());
  29.                 object.put("brandName", goodsBrand.get(i).getBrandName());
  30.                 object.put("brandImg", goodsBrand.get(i).getBrandImg());
  31.                 if(goodsBrand.get(i).getCountryImgUrl()==null){
  32.                     object.put("countryImgUrl", "");
  33.                 }else{
  34.                     object.put("countryImgUrl", goodsBrand.get(i).getCountryImgUrl());
  35.                 }
  36.                 object.put("specialType", goodsBrand.get(i).getSpecialType());
  37.                 array.add(object);
  38.             }
  39.             kit.setByCache(index_Brand, array.toString());
  40.             log.info(new Date()+":缓存数据首页推荐品牌成功。key:"+index_Brand);
  41.         } catch (Exception e) {
  42.             log.error("数据缓存首页推荐品牌异常,请检查RedisUtil方法!。key:"+index_Brand);
  43.         }
  44.     }
  45.     //读取缓存
  46.     public List<GoodsBrand> readIndexBrand(){
  47.         List<GoodsBrand> goodsBrand = new ArrayList<GoodsBrand>();
  48.         try {
  49.             List<com.alibaba.fastjson.JSONObject> list = kit.getArrayByCache(index_Brand);
  50.             for (int i = 0; i < list.size(); i++) {
  51.                 GoodsBrand brand = new GoodsBrand();
  52.                 brand.setId(Integer.parseInt(list.get(i).get("id").toString()));
  53.                 brand.setBrandName(list.get(i).get("brandName").toString());
  54.                 brand.setBrandImg(list.get(i).get("brandImg").toString());
  55.                 if(list.get(i).get("countryImgUrl").toString() != null){
  56.                     brand.setCountryImgUrl(list.get(i).get("countryImgUrl").toString());
  57.                 }else{
  58.                     brand.setCountryImgUrl("");
  59.                 }
  60.                 brand.setSpecialType(list.get(i).get("specialType").toString());
  61.                 goodsBrand.add(brand);
  62.             }
  63.             log.info(new Date()+":读取缓存数据首页推荐品牌成功。key:"+index_Brand);
  64.         } catch (Exception e) {
  65.             // TODO: handle exception
  66.             log.error("读取缓存首页推荐品牌异常,请检查RedisUtil方法!。key:"+index_Brand);
  67.         }
  68.         return goodsBrand;
  69.     }
  70.     /**
  71.      * end
  72.      */
  73. }

注意:redis数据结构以key-value存储,所以将自己的数据结构转换成这种方式去存储,

3):在控制器里面去调用上面接口

这里应该都看得懂,我就不解释啦。里面有打印那些提示,在控制台查看缓存功能是不是成功了!

4)清除缓存

我这里暂时没有做到数据库和redis数据的实时同步。

现在有两个方案可以更新:

(1)如果后台改动数据需要马上更新,那我们就可以在前台触发事件来调用后台清理缓存接口

(2)还有设置一个定时器调用接口,到某个时间段来同步数据

原文地址http://www.bieryun.com/3209.html

 

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
9月前
|
存储 NoSQL Linux
Redis三种集群模式原理与搭建配置
Redis三种集群模式原理与搭建配置
548 0
|
9月前
|
NoSQL Redis CDN
分布式服务器框架之搭建C#+MongoDB+Redis初步
WebAccount站点主要干的事儿是下发 服务器状态信息,这个服务器会和WorldServer建立连接,等所有的GameServer初始化完成之后会同步给WorldServer,WorldServer同步给账号服务器站点,然后账号站点等待玩家请求。
|
9月前
|
NoSQL 算法 中间件
分布式服务器框架之搭建C#+MongoDB+Redis初步
Common类库主要做的是一些大家都需要用到的通用的事情,为了避免重复,所以就提取出来了一个Dll。Common库主要是实现了表格数据的加载模块、在CsRedisClient、MongoClient中间件的基础上进行二次封装。实现了数据库连接、Redis连接、以及数据库和Redis的增删改查断开操作。
|
9月前
|
NoSQL 关系型数据库 MySQL
在 macOS Catalina 10.15 搭建 PHP 开发环境包括PHP的redis扩展
在 macOS Catalina 10.15 搭建 PHP 开发环境包括PHP的redis扩展
177 0
|
10月前
|
监控 NoSQL Java
redis灵魂拷问:怎样搭建一个哨兵主从集群
redis灵魂拷问:怎样搭建一个哨兵主从集群
|
10月前
|
NoSQL Linux Redis
|
11月前
|
消息中间件 缓存 弹性计算
ELK搭建(十):搭建redis运行指标监控平台
Redis作为基于内存的非关系型数据库,常常被应用于热点数据缓存,它很大程度上为我们关系性数据库提供了性能补充。保证redis的高可用,对应整个应用程序的运行至关重要,一个直观的监控redis运行情况的数据看板可以为我们实时了解redis运行情况提供极大的便利。
126 0
ELK搭建(十):搭建redis运行指标监控平台
|
11月前
|
NoSQL Java Redis
【Docker】搭建部署Redis高可用集群实验
【Docker】搭建部署Redis高可用集群实验
456 0
【Docker】搭建部署Redis高可用集群实验
|
11月前
|
NoSQL Redis 数据安全/隐私保护
【Docker】6、Docker搭建Redis高可用Cluster集群环境
本篇文章将使用 docker 搭建 Redis 高可用 Cluster 集群环境,我们采用三主三从模式,使用 6 个节点搭建 Cluster 集群环境
383 0
|
11月前
|
NoSQL Redis 算法
搭建Redis高可用Cluster集群环境
首先搭建单机版 Redis 环境
123 0
搭建Redis高可用Cluster集群环境
推荐文章
更多