RedisTemplate 随意切换多个 db 库 不影响其他线程

本贴最后更新于 1803 天前,其中的信息可能已经天翻地覆

问题描述

原切换 db 的方式会使全局的 redisTemplate 被修改掉,并发量稍微高一点,就会影响到其他线程查询 Redis 数据

//原切换db的方式(错误的) public RedisTemplate<Serializable, Object> initRedis(Integer indexDb){ LettuceConnectionFactory jedisConnectionFactory = (LettuceConnectionFactory) redisTemplate.getConnectionFactory(); jedisConnectionFactory.setDatabase(indexDb); redisTemplate.setConnectionFactory(jedisConnectionFactory); jedisConnectionFactory.resetConnection(); return redisTemplate; }

解决方案,为每一个 db 创建一个 redisTemplate

import java.io.Serializable; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisPassword; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.connection.jedis.JedisClientConfiguration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.stereotype.Component; import lombok.extern.slf4j.Slf4j; import redis.clients.jedis.JedisPoolConfig; @Component @Slf4j public class RedisConfig { @Value("${redis.host}") private String hostName; @Value("${redis.port}") private int port; @Value("${redis.password}") private String passWord; @Value("${redis.maxIdle}") private int maxIdl; @Value("${redis.minIdle}") private int minIdl; @Value("${redis.timeout}") private int timeout; private int defaultDb; @Value("${redis.dbs}") private List<Integer> dbs; public static Map<Integer, RedisTemplate<Serializable, Object>> redisTemplateMap = new HashMap<>(); @PostConstruct public void initRedisTemp() throws Exception { log.info("###### START 初始化 Redis 连接池 START ######"); defaultDb = dbs.get(0); for (Integer db : dbs) { log.info("###### 正在加载Redis-db-" + db+ " ######"); redisTemplateMap.put(db, redisTemplateObject(db)); } log.info("###### END 初始化 Redis 连接池 END ######"); } public RedisTemplate<Serializable, Object> redisTemplateObject(Integer dbIndex) throws Exception { RedisTemplate<Serializable, Object> redisTemplateObject = new RedisTemplate<Serializable, Object>(); redisTemplateObject.setConnectionFactory(redisConnectionFactory(jedisPoolConfig(), dbIndex)); setSerializer(redisTemplateObject); redisTemplateObject.afterPropertiesSet(); return redisTemplateObject; } /** * 连接池配置信息 * * @return */ public JedisPoolConfig jedisPoolConfig() { JedisPoolConfig poolConfig = new JedisPoolConfig(); // 最大连接数 poolConfig.setMaxIdle(maxIdl); // 最小空闲连接数 poolConfig.setMinIdle(minIdl); poolConfig.setTestOnBorrow(true); poolConfig.setTestOnReturn(true); poolConfig.setTestWhileIdle(true); poolConfig.setNumTestsPerEvictionRun(10); poolConfig.setTimeBetweenEvictionRunsMillis(60000); // 当池内没有可用的连接时,最大等待时间 poolConfig.setMaxWaitMillis(10000); // ------其他属性根据需要自行添加------------- return poolConfig; } /** * jedis连接工厂 * * @param jedisPoolConfig * @return */ public RedisConnectionFactory redisConnectionFactory(JedisPoolConfig jedisPoolConfig, int db) { // 单机版jedis RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(); // 设置redis服务器的host或者ip地址 redisStandaloneConfiguration.setHostName(hostName); // 设置默认使用的数据库 redisStandaloneConfiguration.setDatabase(db); // 设置密码 redisStandaloneConfiguration.setPassword(RedisPassword.of(passWord)); // 设置redis的服务的端口号 redisStandaloneConfiguration.setPort(port); // 获得默认的连接池构造器(怎么设计的,为什么不抽象出单独类,供用户使用呢) JedisClientConfiguration.JedisPoolingClientConfigurationBuilder jpcb = (JedisClientConfiguration.JedisPoolingClientConfigurationBuilder) JedisClientConfiguration .builder(); // 指定jedisPoolConifig来修改默认的连接池构造器(真麻烦,滥用设计模式!) jpcb.poolConfig(jedisPoolConfig); // 通过构造器来构造jedis客户端配置 JedisClientConfiguration jedisClientConfiguration = jpcb.build(); // 单机配置 + 客户端配置 = jedis连接工厂 return new JedisConnectionFactory(redisStandaloneConfiguration, jedisClientConfiguration); } private void setSerializer(RedisTemplate<Serializable, Object> template) { template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); } public RedisTemplate<Serializable, Object> getRedisTemplateByDb(int db){ return redisTemplateMap.get(db); } public RedisTemplate<Serializable, Object> getRedisTemplate(){ return redisTemplateMap.get(defaultDb); } }

application.yml

redis: host: 192.168.100.77 port: 6379 password: 123456 # 密码(默认为空) maxIdle: 10 minIdle: 5 timeout: 1000 dbs: 0,1 # 可以指定多个,用“,”隔开,写在第一个的为defaultDB

使用方法

@Resource RedisConfig redisConfig; //无参数时默认查询defaultDB 也就是配置文件中写在第一个的db redisConfig.getRedisTemplate().opsForValue()..... //可以指定具体查询哪个DB redisConfig.getRedisTemplate(1).opsForValue().....
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    948 引用 • 1460 回帖
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    284 引用 • 248 回帖 • 1 关注
1 操作
724555508 在 2020-08-16 21:15:02 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • WiFiDog

    WiFiDog 是一套开源的无线热点认证管理工具,主要功能包括:位置相关的内容递送;用户认证和授权;集中式网络监控。

    1 引用 • 7 回帖 • 612 关注
  • SEO

    发布对别人有帮助的原创内容是最好的 SEO 方式。

    36 引用 • 200 回帖 • 38 关注
  • DNSPod

    DNSPod 建立于 2006 年 3 月份,是一款免费智能 DNS 产品。 DNSPod 可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。

    6 引用 • 26 回帖 • 528 关注
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 118 关注
  • Visio
    1 引用 • 2 回帖 • 1 关注
  • Laravel

    Laravel 是一套简洁、优雅的 PHP Web 开发框架。它采用 MVC 设计,是一款崇尚开发效率的全栈框架。

    19 引用 • 23 回帖 • 742 关注
  • TGIF

    Thank God It's Friday! 感谢老天,总算到星期五啦!

    291 引用 • 4495 回帖 • 664 关注
  • Pipe

    Pipe 是一款小而美的开源博客平台。Pipe 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    134 引用 • 1127 回帖 • 111 关注
  • 酷鸟浏览器

    安全 · 稳定 · 快速
    为跨境从业人员提供专业的跨境浏览器

    3 引用 • 59 回帖 • 52 关注
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1795 回帖
  • Hadoop

    Hadoop 是由 Apache 基金会所开发的一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。

    93 引用 • 122 回帖 • 613 关注
  • Thymeleaf

    Thymeleaf 是一款用于渲染 XML/XHTML/HTML5 内容的模板引擎。类似 Velocity、 FreeMarker 等,它也可以轻易的与 Spring 等 Web 框架进行集成作为 Web 应用的模板引擎。与其它模板引擎相比,Thymeleaf 最大的特点是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个 Web 应用。

    11 引用 • 19 回帖 • 397 关注
  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    201 引用 • 120 回帖
  • QQ

    1999 年 2 月腾讯正式推出“腾讯 QQ”,在线用户由 1999 年的 2 人(马化腾和张志东)到现在已经发展到上亿用户了,在线人数超过一亿,是目前使用最广泛的聊天软件之一。

    45 引用 • 557 回帖 • 1 关注
  • Webswing

    Webswing 是一个能将任何 Swing 应用通过纯 HTML5 运行在浏览器中的 Web 服务器,详细介绍请看 将 Java Swing 应用变成 Web 应用

    1 引用 • 15 回帖 • 643 关注
  • Mac

    Mac 是苹果公司自 1984 年起以“Macintosh”开始开发的个人消费型计算机,如:iMac、Mac mini、Macbook Air、Macbook Pro、Macbook、Mac Pro 等计算机。

    167 引用 • 597 回帖 • 3 关注
  • Gitea

    Gitea 是一个开源社区驱动的轻量级代码托管解决方案,后端采用 Go 编写,采用 MIT 许可证。

    5 引用 • 16 回帖 • 1 关注
  • WordPress

    WordPress 是一个使用 PHP 语言开发的博客平台,用户可以在支持 PHP 和 MySQL 数据库的服务器上架设自己的博客。也可以把 WordPress 当作一个内容管理系统(CMS)来使用。WordPress 是一个免费的开源项目,在 GNU 通用公共许可证(GPLv2)下授权发布。

    46 引用 • 114 回帖 • 166 关注
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖 • 1 关注
  • VirtualBox

    VirtualBox 是一款开源虚拟机软件,最早由德国 Innotek 公司开发,由 Sun Microsystems 公司出品的软件,使用 Qt 编写,在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。

    10 引用 • 2 回帖 • 17 关注
  • Sandbox

    如果帖子标签含有 Sandbox ,则该帖子会被视为“测试帖”,主要用于测试社区功能,排查 bug 等,该标签下内容不定期进行清理。

    442 引用 • 1238 回帖 • 598 关注
  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖
  • danl
    181 关注
  • JVM

    JVM(Java Virtual Machine)Java 虚拟机是一个微型操作系统,有自己的硬件构架体系,还有相应的指令系统。能够识别 Java 独特的 .class 文件(字节码),能够将这些文件中的信息读取出来,使得 Java 程序只需要生成 Java 虚拟机上的字节码后就能在不同操作系统平台上进行运行。

    180 引用 • 120 回帖 • 2 关注
  • Swift

    Swift 是苹果于 2014 年 WWDC(苹果开发者大会)发布的开发语言,可与 Objective-C 共同运行于 Mac OS 和 iOS 平台,用于搭建基于苹果平台的应用程序。

    34 引用 • 37 回帖 • 557 关注
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖
  • 深度学习

    深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

    43 引用 • 44 回帖